Operator Reference

Aria's operators are ordered by precedence from highest (binds tightest) to lowest.

Precedence Table

LevelOperatorDescription
16. ?. [] () .{}Field access, optional chain, index, call, record update
15? ! (postfix)Error propagation, assert success
14- ! ~ (prefix)Negate, logical NOT, bitwise NOT
13* / %Multiply, divide, modulo
12+ -Add, subtract
11<< >>Bit shift left, right
10&Bitwise AND
9^Bitwise XOR
8|Bitwise OR
7.. ..=Range (exclusive, inclusive)
6== != < > <= >=Comparison
5&&Logical AND
4||Logical OR
3??Null coalesce
2|>Pipeline
1:= =Binding, assignment

Key Operators

Pipeline |>

Passes the left-hand value as the first argument to the right-hand function:

result := data
    |> parse?
    |> validate?
    |> transform
    |> serialize?

// Equivalent to:
result := serialize(transform(validate(parse(data)?)?)?)?

Error Propagation ?

If the expression is Err, return the error immediately. If Ok, unwrap the value:

content := io.readFile(path)?   // returns error or unwraps

Assert Success !

Unwrap or panic:

value := something()!   // panics with stack trace on error

Optional Chaining ?.

Short-circuit to None if any step is None:

city := user?.address?.city   // Option[str]

Null Coalesce ??

Provide a default for None:

name := user?.name ?? "Anonymous"

Record Update .{...}

Create a copy with some fields changed:

updated := config.{port: 9090, debug: true}

Range .. and ..=

0..10     // 0, 1, 2, ..., 9
0..=10    // 0, 1, 2, ..., 10
s[2..5]   // substring slice

Compound Assignment

Compound assignment operators modify a mutable variable in place:

mut x := 10
x += 5    // x = x + 5
x -= 3    // x = x - 3
x *= 2    // x = x * 2
x /= 4    // x = x / 4
x %= 3    // x = x % 3

String Interpolation

Not technically an operator, but important — expressions inside { } in string literals are evaluated:

println("Hello, {name}! Result: {2 + 2}")
println("Config: {config.display()}")

No Implicit Conversions

All operators require matching types. i32 + i64 is a compile error — you must explicitly convert:

a: i32 = 5
b: i64 = 10
c := i64(a) + b   // explicit widening