Rune types

Types in Rune are identified uniquely by their item. An item path is a scope-separated identifier, like std::f64. This particular item identifies a type.

These items can be used to perform basic type checking using the is and is not operations, like this:

assert!(() is Tuple, "tuples should be tuples"); assert!((1, 2) is Tuple, "tuples should be tuples"); assert!(true is bool, "bools should be bools"); assert!('a' is char, "chars should be chars"); assert!(b'a' is u64, "bytes should be unsigned integers"); assert!(42 is i64, "integers should be integers"); assert!(42.1 is f64, "floats should be floats"); assert!("hello" is String, "strings should be strings"); assert!("x" is not char, "strings are not chars"); assert!(#{"hello": "world"} is Object, "objects should be objects"); assert!(["hello", "world"] is Vec, "vectors should be vectors");
$> cargo run -- run scripts/book/types/types.rn

Conversely, the type check would fail if you're providing a value which is not of that type.

assert!(["hello", "world"] is String, "vectors should be strings");
$> cargo run -- run scripts/book/types/bad_type_check.rn == ! (panicked `assertion failed: vectors should be strings` (at 12)) (133.3µs) error: virtual machine error ┌─ scripts/book/types/bad_type_check.rn:2:5 │ 2 │ assert!(["hello", "world"] is String, "vectors should be strings"); │ ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ panicked `assertion failed: vectors should be strings`

This gives us insight at runtime which type is which, and allows Rune scripts to make decisions depending on what type a value has.

fn dynamic_type(n) { if n is String { "n is a String" } else if n is Vec { "n is a vector" } else { "n is unknown" } } println!("{}", dynamic_type("Hello")); println!("{}", dynamic_type([1, 2, 3, 4])); println!("{}", dynamic_type(42));
$> cargo run -- run scripts/book/types/type_check.rn n is a String n is a vector n is unknown

A tighter way to accomplish this would be by using pattern matching, a mechanism especially suited for many conditional branches. Especially when the branches are different types or variants in an enum.

fn dynamic_type(n) { match n { n if n is String => "n is a String", n if n is Vec => "n is a vector", _ => "n is unknown", } } println!("{}", dynamic_type("Hello")); println!("{}", dynamic_type([1, 2, 3, 4])); println!("{}", dynamic_type(42));
$> cargo run -- run scripts/book/types/type_check_patterns.rn n is a String n is a vector n is unknown