Branches & Patterns
Branches define a machine’s behavior. Each branch describes which arguments are accepted and what happens when they are received.
Branch Syntax
pattern+ -> { body }
pattern+— one or more patterns (parameters){ body }— branch body containing expressions
Patterns
A pattern declares a parameter with a name, a type, and an optional default value:
ident Type # typed parameter
ident Type.default # parameter with default value
_ # wildcard — ignored parameter
Typed Parameters
sum is {
n i64 acc i64 -> {
when 0 == n {
true -> { rt_write(1 "done\n" 5) }
false -> { self(n-1 acc+n) }
}
}
}
This branch takes two i64 parameters: n and acc.
Default Values
A default value is specified after the type, separated by a dot (.):
main is {
_ i64.0 -> {
counter(5)
}
}
_ i64.0 — a wildcard parameter of type i64 with default value 0. Parameters with defaults do not participate in branch signature matching.
Wildcard
The _ symbol means the argument is ignored. It does not bind a variable:
pong is {
_ i64.0 -> {
rt_write(1 "pong\n" 5)
}
}
Branch Dispatch
When a machine is called, the compiler selects the matching branch based on the types of the provided arguments. Branch dispatch is O(1) — argument types are hashed at compile time.
Only non-default, non-wildcard pattern types participate in the hash. For example:
counter is {
n i64 -> { ... }
}
A call counter(5) matches this branch because 5 is i64 and the branch expects i64.
Multiple Parameters
Parameters are separated by spaces:
worker is {
steps i64 acc1 i64 acc2 i64 -> {
when 1 <= steps {
true -> { self(steps-1 acc2 acc1+acc2) }
false -> { rt_write(1 ".\n" 2) }
}
}
}
Three parameters: steps, acc1, and acc2, all of type i64.
Scope
Each branch has its own scope. Variables declared through patterns are only accessible within that branch’s body.