Match
Gale matches values by shape. Each arm pairs a pattern with a result, the
first pattern that fits wins, and the compiler rejects a match that leaves a
shape uncovered. A pattern name binds a fresh value; pinning it with ^
compares against a value already in scope.
module matching
pub fn describe(status: :idle | :running | :done) -> Binary { match status { :idle -> "waiting" :running -> "busy" :done -> "finished" }}match walks its arms top to bottom and picks the first pattern that fits the
value. Every shape of the matched type must be covered — this is checked at
compile time, so forgetting an arm is an error, not a runtime surprise:
pub fn broken(status: :idle | :running | :done) -> Binary { match status { :idle -> "waiting" :running -> "busy" }}A literal arm answers one value. A guard (when) attaches a Boolean test to
an arm: the arm is chosen only when both the pattern fits and the test holds.
_ fits anything, so it closes out the remaining cases.
module matching
pub fn stock(count: Integer) -> Binary { match count { 0 -> "empty" n when n < 10 -> "low" _ -> "many" }}A name written in a pattern is a new binding for whatever value sits at
that position — it never compares against anything you already hold. _
ignores a position. Used together they destructure data into fresh names:
module matching
pub type Entry = (Integer, Binary)
pub fn name_of(entry: Entry) -> Binary { match entry { (_, name) -> name }}
pub fn first(items: List<Integer>, fallback: Integer) -> Integer { match items { [] -> fallback [head | _] -> head }}So (wanted, _) would match every entry: it simply names the first
element wanted. To compare a position against a value you already hold,
pin the name with ^. A pin binds nothing; the arm fits only when the
position equals the pinned value at the moment the match starts:
module matching
pub type Entry = (Integer, Binary)
pub fn has_id(entry: Entry, wanted: Integer) -> Boolean { match entry { (^wanted, _) -> true _ -> false }}Because a pinned arm can fail on a value its shape admits, it never counts
toward coverage — the _ fallback above is required, not decorative. The
same ^name works anywhere a pattern does, including receive, where
pinning a reply tag lets a process skip messages it is not waiting for
(see Processes).