Skip to content

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).