Bindings: let and var
A binding associates a name with a value or computation. let creates an immutable reference; var creates a mutable one.
let fixedNumericBinding = 10
let fixedStringBinding = "the quick brown fox"
var value = 10
value = 20
Functions are bindings too
When a let binding takes parameters, it becomes a function — re-evaluated every time it's called, rather than computed once:
let alwaysTen() = 10
let plusOne(value: int) = value + 1
let add(left, right) = left + right
Execution blocks
Bindings can nest inside each other, and a block can compute a result with return:
let value = {
let connection = resolveDatabaseConnection()
let buildRequest = constructRequest()
return connection.performQuery(buildRequest)
}
Parameter and return types can be inferred or written explicitly:
# The input and output are listed explicitly.
let square(input: i32) : i32 {
return input * input
}
A gotcha: top-level bindings resolve lazily
Global (top-level) bindings are resolved the first time they're used at runtime — not in the order they're written in the file:
# In program order, first comes before second.
let first = println("first")
let second = println("second")
# But global bindings are resolved in runtime order,
# so "second" prints before "first".
entrypoint main() {
second
first
}