Skip to main content

Operators

Arithmetic

OperatorNameExampleResult
+Addition3 + 47
-Subtraction10 - 37
*Multiplication3 * 412
/Division10 / 42 (int÷int) / 2.5 (float)
%Remainder (modulus)10 % 31
-Unary negation-5-5

Bitwise

OperatorNameExampleResult
&Bitwise AND6 & 32
|Bitwise OR5 | 27
^Bitwise XOR7 ^ 34
~Bitwise NOT (unary)~0-1
<<Left shift1 << 416
>>Right shift64 >> 216

Logical

OperatorNameExampleResult
&&Logical AND (short-circuit)true && falsefalse
||Logical OR (short-circuit)false || truetrue
!Logical NOT (unary)!truefalse

&& and || are short-circuit: the right operand is not evaluated if the left operand determines the result. Both operands must be bool; mixing types produces a TypeError.

Comparison

OperatorNameExampleResult
==Equal3 == 3true
!=Not equal3 != 4true
<Less than1 < 2true
>Greater than2 > 1true
<=Less than or equal2 <= 2true
>=Greater than or equal3 >= 2true

Equality (==, !=) requires both operands to be the same type — mixing int and float produces a TypeError. Ordering operators (<, >, <=, >=) allow int vs float comparisons by promoting the integer to float.

Pipe

OperatorNameDescription
|>PipePass left-hand value as the first argument to the right-hand function

The pipe operator threads a value through a chain of function calls left-to-right. x |> f is equivalent to f(x). When the right-hand side is a call expression with arguments, the piped value is inserted as the first argument: 5 |> add(3) is equivalent to add(5, 3).

fn double(x) { return x * 2 }
fn add(a, b) { return a + b }

// Simple pipe
let n = 5 |> double // 10

// Chained pipes — left-associative
let m = 3 |> double |> double // 12

// Pipe with extra arguments (value inserted as first arg)
let r = 5 |> add(3) // add(5, 3) = 8

// Pipe to print
"hello" |> print

// Pipe with arithmetic on the left
let x = (2 + 3) |> double // 10

Pipes are left-associative and have lower precedence than all other operators, so the entire expression to the left of |> is fully evaluated before being passed to the function on the right.

Precedence

Operators bind from tightest to loosest in this order:

  1. Unary: ~, !, -
  2. Multiplicative: *, /, %
  3. Additive: +, -
  4. Shifts: <<, >>
  5. Bitwise AND: &
  6. Bitwise XOR: ^
  7. Bitwise OR: |
  8. Comparison: ==, !=, <, >, <=, >=
  9. Logical AND: &&
  10. Logical OR: ||
  11. Pipe: |> (lowest — entire left expression is the piped value)
let x = 2 + 3 * 4
let y = 1 << 2 & 15
let z = 1 < 2 && 3 > 0

Runtime Errors

The following operations produce runtime errors:

  • Division by zero: x / 0
  • Remainder by zero: x % 0
  • Invalid shift amount (negative or ≥ 64): 1 << 64
  • Type mismatch: 1 + true, 1.0 & 2, 1 == 1.0