Syntax
Bindings, blocks and functions. Almost everything is an expression, and nothing mutates.
Bindings
A binding is name = expression. Bindings are immutable. Rebinding a name
shadows the earlier one from that point on. An annotation goes between the name and the
=, and it is documentation the compiler checks, not information it needs:
types are inferred at their most general.
units = 4
units = units + 2
restock Int = int.max(units * 2, 12)
(total, saved) = price_line(unit_cents, units)
Almost everything is an expression. if yields a value, and so does a
{ ... } block. There is no return: a function's value is its
body's last expression. Parentheses build tuples; braces group.
Functions
fn name(params) ReturnType { body } declares a function. Parameter types are
written after the name. A lambda is fn(x) body and carries no return-type
slot. A closure captures the value a name holds when the closure is made; rebinding the
name afterwards does not reach back into the closure.
/** Returns a function that adds `k`. The returned closure carries `k` with it. */
fn adder(k Int) fn(Int) Int {
fn(x) x + k
}
pub fn main() {
base = 10
add_base = adder(base)
base = 100
println('add_base(1) = ${add_base(1)}, base is now ${base}')
}