Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Operators

Arithmetic

+, -, *, /, %, ^ work on int and float. Both operands must have the same type — Abra does not auto-convert between int and float.

let x = 5 + 2       // 7
let y = 7.5 - 2.5   // 5.0
let r = 13 % 5      // 3 (modulo)
let p = 2 ^ 8       // 256 (power)

Unary - negates a number:

let n = -5
let f = -3.14

String concatenation

The .. operator concatenates two values into a string. Either operand may be any type that implements the ToString interface, so you can mix strings, numbers, and other values without converting them first:

let name = "Merlin"
let age = 73
let msg = name .. " is " .. age .. " years old."
// "Merlin is 73 years old."

+ is not for string concatenation — that’s only for numbers.

Comparison

== and != work on any type that implements Equal. <, <=, >, >= work on any type that implements Ord.

let a = 5 == 5      // true
let b = "x" != "y"  // true
let c = 3 < 7       // true
let d = "apple" < "banana"  // true (lexicographic)

Logical

and, or, not are keywords (not &&, ||, !):

if x > 0 and x < 10 {
    println("in range")
}

if not done {
    keep_going()
}

and and or short-circuit.

Assignment

Plain assignment uses =. Compound assignment operators are also available:

var x = 0
x = 10      // simple
x += 5      // x = x + 5
x -= 1      // x = x - 1
x *= 2      // x = x * 2
x /= 4      // x = x / 4
x %= 3      // x = x % 3

Only var bindings, array elements, and struct fields can be assigned to.

Indexing

arr[i] and arr[i] = value index into arrays. The same syntax works on any type that implements the Index interface, including map and JsonValue:

let arr = [10, 20, 30]
let first = arr[0]     // 10
arr[1] = 99            // arr = [10, 99, 30]

use core/map
let m: map<string, int> = map.new()
m["alice"] = 100        // calls Index.index_set
let score = m["alice"]  // calls Index.index_get

Unwrap (!)

Postfix ! extracts the value from an option or result, panicking if it’s none / err. Use it when you know the value is present:

let n = "42".to_int()!     // panics if not a valid int

Try (?)

Postfix ? propagates none/err to the caller. The enclosing function must return a compatible option or result:

use core/fs

fn read_two(a: string, b: string) -> result<string, FsError> {
    let first = read(a)?       // early-return on err
    let second = read(b)?
    .ok(first .. second)
}

Operator precedence

From lowest to highest:

PrecedenceOperatorsDescription
1and, orlogical
2==, !=equality
3..string format/concat
5<, <=, >, >=comparison
6+, - (binary or unary)additive
7*, /multiplicative
8%modulo
9^power
10notprefix
11.fieldmember access
12[index]index
13f(args)function call
14!unwrap
15?try