Operators

Arithmetic Operators #

Operator Description Example
+ Addition 3 + 25
- Subtraction 10 - 46
* Multiplication 3 * 412
/ Division 10 / 33
% Modulo 10 % 31
** Exponentiation 2 ** 8256

Comparison Operators #

Operator Description Example
== Equal x == 5
!= Not equal x != 0
< Less than x < 10
> Greater than x > 0
<= Less or equal x <= 100
>= Greater or equal x >= 1

Logical Operators #

Operator Description Example
&& Logical AND a && b
|| Logical OR a || b
! Logical NOT !flag

Assignment Operators #

Operator Description Example
= Assignment x = 10
+= Add and assign x += 5
-= Subtract and assign x -= 3
*= Multiply and assign x *= 2
/= Divide and assign x /= 4
%= Modulo and assign x %= 3

Pipe Operator |>

The pipe operator passes the left expression as the first argument to the right function. This creates a natural top-to-bottom data flow:

// Without pipe — hard to read (inside-out)
let result = collect(filter(map(list, |x| x * 2), |x| x > 5))

// With pipe — natural flow
let result = list
    |> map(|x| x * 2)
    |> filter(|x| x > 5)
    |> collect()

How It Works #

a |> f(b, c) transforms to f(a, b, c) — the left side becomes the first argument.

"  Hello World  "
    |> string.trim()
    |> string.split(" ")
    |> Array.map(|s| string.to_upper(s))
    |> Array.join(", ")

Pipe with Placeholder _

When the piped value shouldn't be the first argument:

users
    |> sort(_, by: .name)
    |> group(_, key: |u| u.age)

Tap Operator &.

Executes a side effect without breaking the chain — the original value passes through unchanged. Perfect for debugging and logging:

list
    |> sort()
    &. print()           // prints the sorted list, passes it along
    |> filter(|x| x > 0)
    &. |x| log(x)        // debug log
    |> collect()

How It Works #

a &. f() calls f(a) for its side effect, then returns a unchanged.


Optional Chaining ?.

Safely access fields on values that might be nil:

let city = user?.address?.city    // nil if any part is nil

Without optional chaining, you'd need nested nil checks:

// Equivalent without ?.
let city = if user != nil {
    if user.address != nil {
        user.address.city
    } else { nil }
} else { nil }

Null Coalesce ??

Provide a default value when the left side is nil:

let name = user?.name ?? "Anonymous"
let port = config?.port ?? 8080

Combining with Optional Chaining #

let city = user?.address?.city ?? "unknown"

Error Propagation ?

Propagates errors up the call stack, similar to Rust:

fn read_config(path: str) -> Result<Config, Error> {
    let text = fs.read(path)?        // returns early on error
    let config = json.parse(text)?
    Result.Ok(config)
}

When ? is applied to a Result.Err, the function immediately returns that error. When applied to Result.Ok(value), it unwraps to value.


Spread Operator ...

Spread elements into arrays or structs:

let a = [1, 2, 3]
let b = [0, ...a, 4, 5]   // [0, 1, 2, 3, 4, 5]

let base = { name: "Alice" }
let full = { ...base, age: 30 }

Range Operators #

Operator Description Example
.. Exclusive range 0..10 → 0 to 9
..= Inclusive range 0..=10 → 0 to 10
for i in 0..5 {     // 0, 1, 2, 3, 4
    print(i)
}

for i in 0..=5 {    // 0, 1, 2, 3, 4, 5
    print(i)
}

Operator Precedence #

From highest to lowest:

  1. Unary: -x, !x
  2. Exponentiation: **
  3. Multiplicative: *, /, %
  4. Additive: +, -
  5. Range: .., ..=
  6. Comparison: <, >, <=, >=
  7. Equality: ==, !=
  8. Logical AND: &&
  9. Logical OR: ||
  10. Null coalesce: ??
  11. Pipe: |>
  12. Tap: &.
  13. Assignment: =, +=, -=, *=, /=, %=
enespt-br