Skip to content

Operators

Arithmetic, comparison, logic, bitwise operations, assignment, ranges, casts, and piping.

Updated View as Markdown

Operators combine, inspect, or update values. Parsing determines grouping; semantic checking determines whether the operand types support the requested operation.

Arithmetic

Operator Meaning
+ Addition
- Subtraction
* Multiplication
/ Division
% Remainder
prefix - Negation
subtotal := price * quantity
remainder := total % page_size
offset := -position

Integer division and floating-point division retain their operand category. The checker does not turn an integer expression into floating point merely because / appears.

For non-primitive values, +, -, *, and / dispatch through the Numeric contract. Prefix - dispatches through Neg. % is not supplied by Numeric and should be treated as a primitive numeric operation unless a future dedicated trait is added.

Comparison

Operator Meaning
== Equal
!= Not equal
< Less than
<= Less than or equal
> Greater than
>= Greater than or equal
same := left == right
within := value >= minimum and value <= maximum

Equality on non-primitive values uses Equatable. Ordering uses Comparable[T]. Comparisons do not chain: write a < b and b < c, not a < b < c.

Equality is a value contract. It is not a source-level pointer identity test. A user-defined implementation must preserve the usual equality laws, and a Hashable implementation must give equal values equal hash codes.

Logic

and and or are short-circuiting boolean operators. && and || are accepted aliases. Prefix not and ! are aliases for logical negation.

if user.is_active() and user.can_edit(document) {
    edit(document)
}

The right operand of and is evaluated only when the left is true. The right operand of or is evaluated only when the left is false.

ready := cached or initialize()

Both operands must type-check as bool. Atoll does not apply truthiness to numbers, strings, collections, or optional values.

For non-primitive values, prefix ! or not can dispatch through Not.

Bitwise

Operator Meaning
& Bitwise AND
| Bitwise OR
^ Bitwise XOR
~ Bitwise complement
<< Left shift
>> Right shift
flags := 0b1010
mask := 0b1100

shared := flags & mask
combined := flags | mask
toggled := flags ^ mask
shifted := flags << 2

Primitive integers lower directly. User-defined types can participate through BitAnd, BitOr, BitXor, BitNot, Shl, and Shr.

Prefix & is contextually different from infix &: it takes a reference to an expression.

view: &Packet = &packet

Reference rules are covered in References.

Assignment

= updates an existing mutable place. It does not declare a new inferred binding; declarations use :=.

mut count := 0
count = count + 1

Compound assignments read, operate, and write the same place.

Operators
+=, -=, *=, /=, %=
&=, |=, ^=, <<=, >>=
??=
mut total := 0
total += price

mut cached: string? = None
cached ??= compute_name()

The target must be assignable and mutable. This includes mutable locals, mutable fields reached through a mutable receiver, and supported indexed places.

Options

?? chooses the successful payload from its left side or evaluates its right side as a fallback. It works with the current Option and Result coalescing rules.

name := configured_name ?? "anonymous"

The right side is lazy. ?. performs option-safe member access and preserves absence through a chain.

city := account?.profile?.city

??= stores the fallback only when the target lacks a successful payload. Detailed typing and control flow are in Option and Result.

Propagation

Postfix ? propagates failure or absence according to the enclosing function contract.

user := load_user(id)?

On Result, it extracts Ok and returns Err from a compatible fallible function. On Option, it extracts Some and returns None from a compatible optional function. See Propagation.

Ranges

start..end excludes the upper endpoint. start..=end includes it.

for index in 0..items.len() {
    use(items[index])
}

match status {
    200..=299 => success()
    _ => failure()
}

Ranges appear in iteration and patterns. They are not Python-style slice syntax; slices use their own indexing and range support as provided by the collection type.

Membership

value in collection asks whether the right operand contains the left.

allowed := role in permitted_roles

The type must provide a supported membership operation. The same in token is the separator in an iteration loop, where the parser recognizes the loop-head context.

Casts

value as T requests an explicit conversion.

small := count as u16
whole := ratio as int

The semantic checker must know a valid primitive or representation conversion. Writing an unrelated target type does not make the conversion legal.

Atoll’s current expression AST does not implement the legacy value is Type runtime type-test proposal. Use enum or union pattern matching to refine a closed set of alternatives.

Pipeline

value |> function forwards the left value to the right call.

answer := input |> parse |> normalize

When the right side already has arguments, the piped value becomes the leading argument.

page := records |> take(20)

Pipeline syntax changes call shape, not evaluation semantics. Each stage is still type-checked as an ordinary function call.

Precedence

From tightest to loosest, the current parser groups:

Level Forms
Postfix member access, calls, indexing, casts, ?, catch
Prefix -, !, not, ~, &
Coalescing ??
Multiplicative *, /, %
Additive +, -
Shifts <<, >>
Bitwise AND &
Bitwise XOR ^
Bitwise OR |
Ranges .., ..=
Comparison equality, ordering, in
Logical AND and, &&
Logical OR or, ||
Pipeline |>
Assignment = and compound assignments

Assignment is right-associative. Most binary operators are left-associative; comparison and range chains should be written explicitly. Parentheses are preferable whenever mixed operator families would make intent unclear.

Navigation

Type to search…

↑↓ navigate↵ selectEsc close