Operator Reference
Aria's operators are ordered by precedence from highest (binds tightest) to lowest.
Precedence Table
| Level | Operator | Description |
|---|---|---|
| 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