Operators & Expressions

Arithmetic

tape
let sum = a + b;
let diff = a - b;
let prod = a * b;
let quot = a / b;
let rem = a % b;

Compound assignment

tape
x += 1;
x -= 1;
x *= 2;
x /= 2;
x %= 3;
x &= mask;
x |= flag;
x ^= bits;
x <<= 1;
x >>= 1;

Bitwise

tape
let bits_and = a & b;
let bits_or = a | b;
let bits_xor = a ^ b;
let bits_not = ~a;
let shl = a << 2;
let shr = a >> 1;

Comparison

tape
a == b    a != b
a < b     a <= b
a > b     a >= b

Logical

tape
let both = x && y;
let either = x || y;
let negated = !flag;

Pipe operator

tape
let result = data
    |> parse()
    |> validate()
    |> transform();

The pipe operator passes the left-hand value as the first argument to the right-hand function.

Type cast

tape
let wide: i64 = narrow as i64;
let truncated: u8 = big as u8;
let ptr: *u8 = &status as *u8;    // address-of then cast

Prefix operators (&, *, -, !, ~) bind tighter than as/is:

tape
&x as *u8      // → (&x) as *u8
*ptr as i64    // → (*ptr) as i64
-x as f64     // → (-x) as f64

To cast before applying a prefix, use explicit parentheses:

tape
*(ptr as *i64)   // cast pointer, then dereference
-(x as f64)      // cast to float, then negate

Type checking with is

tape
if (widget is *component[@dispatch render]) {
    widget.render();
}

The is operator checks whether a value satisfies a component constraint at runtime. It has the same precedence as as.

String interpolation

tape
let name = "world";
let msg = "Hello, {name}!";
let expr = "2 + 2 = {2 + 2}";

Expressions inside {} within string literals are evaluated and converted to string.

Array literals

tape
let items = [1, 2, 3, 4, 5];
let matrix = [[1, 0], [0, 1]];

Last modified: