Operators and arithmetic
XS has the usual arithmetic and comparison operators, plus a pipe operator, null coalescing, and optional chaining.
println(3 + 4) -- 7
println(10 - 3) -- 7
println(4 * 5) -- 20
println(10 / 3) -- 3 (integer division truncates toward zero)
println(10 % 3) -- 1
println(2 ** 10) -- 1024
println(-7 // 2) -- -4 (floor division: toward negative infinity)
Integer division (/) truncates toward zero, so (-7) / 2 is -3, not -4. Floor division (//) rounds toward negative infinity.
Division by zero raises a catchable runtime error -- it does not silently produce null or NaN:
try {
let d = 10 / 0
} catch e {
println(e.kind) -- division by zero
}
Integers are signed 64-bit and promote to arbitrary-precision bigints on overflow:
println(2 ** 100)
-- 1267650600228229401496703205376
println(5 == 5) -- true
println(5 != 3) -- true
println(3 < 5) -- true
println(5 >= 5) -- true
-- spaceship: returns -1, 0, or 1
println(5 <=> 3) -- 1
println(3 <=> 5) -- -1
println(5 <=> 5) -- 0
Both keyword and symbol forms work. They short-circuit and return the last evaluated operand, not necessarily true or false.
println(true and false) -- false
println(true && false) -- false
println(false or true) -- true
println(false || true) -- true
println(not true) -- false
println(!true) -- false
x |> f passes x as the first argument to f. Chain multiple pipes to build readable data pipelines.
fn double(x) { x * 2 }
fn inc(x) { x + 1 }
let result = 5 |> double |> inc
println(result) -- 11
-- works with multi-arg functions too
let n = [1, 2, 3] |> len
println(n) -- 3
?? returns the left side when it is not null, otherwise the right side.
let val = null ?? 42
println(val) -- 42
let other = 10 ?? 99
println(other) -- 10
?. short-circuits to null when the receiver is null, instead of throwing.
let obj = #{"a": #{"b": 42}}
println(obj?.a?.b) -- 42
println(obj?.x?.y) -- null (no error)
println(2 in [1, 2, 3]) -- true
println("ell" in "hello") -- true (substring)
println("a" in #{"a": 1}) -- true (map key)
let r = 1..5
println(3 in r) -- true (range)
println(5 not in [1, 2, 3]) -- true