Pattern Matching
Pattern matching lets you destructure and inspect values.
Pattern Types
Literal Patterns
Match exact values:
lumen
match n
0 -> "zero"
1 -> "one"
2 -> "two"
_ -> "many"
endWorks with: Int, Float, Bool, String
Wildcard Pattern
Match anything:
lumen
match x
0 -> "zero"
_ -> "not zero"
endBinding Patterns
Capture matched value:
lumen
match n
0 -> "zero"
x -> "got {x}"
endTuple Patterns
lumen
match point
(0, 0) -> "origin"
(x, 0) -> "on x-axis"
(0, y) -> "on y-axis"
(x, y) -> "({x}, {y})"
endList Patterns
lumen
match items
[] -> "empty"
[x] -> "one: {x}"
[x, y] -> "two: {x}, {y}"
[first, ...rest] -> "first: {first}, rest: {length(rest)}"
endWith rest capture:
lumen
match items
[first, second, ...rest] -> # first two elements, rest in list
[...rest, last] -> # all but last in rest, last separately
endRecord Patterns
lumen
match user
User(name: "Admin", ..) -> "administrator"
User(name: n, active: true, ..) -> "active: {n}"
User(active: false, ..) -> "inactive"
endEnum Patterns
Simple enum:
lumen
match status
Pending -> "waiting"
Active -> "running"
Done -> "complete"
endWith data:
lumen
match result
Ok(value) -> "success: {value}"
Err(msg) -> "error: {msg}"
endType Patterns
Check type in unions:
lumen
match value
n: Int -> "int: {n}"
s: String -> "string: {s}"
b: Bool -> "bool: {b}"
endGuard Patterns
Add conditions:
lumen
match n
x if x < 0 -> "negative"
x if x == 0 -> "zero"
x if x < 10 -> "small positive"
_ -> "large positive"
endOr Patterns
Match multiple patterns:
lumen
match c
"a" | "e" | "i" | "o" | "u" -> "vowel"
_ -> "consonant"
endNested Patterns
lumen
match result
Some(Ok(value)) -> "success: {value}"
Some(Err(msg)) -> "failed: {msg}"
None -> "nothing"
endMatch Expression
Match returns a value:
lumen
let label = match status
Pending -> "pending"
Active -> "active"
Done -> "done"
endEach arm must return the same type.
Match Statement
Match can be used as a statement:
lumen
match status
Pending -> print("still waiting")
Active -> print("now active")
Done -> print("completed")
endDestructuring in let
Patterns work in let bindings:
lumen
let (a, b) = (1, 2)
let [first, ...rest] = [1, 2, 3, 4]
let Point(x, y) = point
let User(name: n, ..) = userDestructuring in for
lumen
for (index, item) in enumerate(items)
print("{index}: {item}")
end
for [key, value] in pairs
print("{key} = {value}")
endPattern Matching Rules
- Patterns are tried in order — First match wins
- Matches must be exhaustive — Use
_for fallback - Guards are evaluated after match — Pattern must match first
- Bindings must be unique — Can't bind same name twice
Examples
HTTP Status
lumen
cell status_message(code: Int) -> String
match code
200 -> "OK"
201 -> "Created"
204 -> "No Content"
400 -> "Bad Request"
401 -> "Unauthorized"
403 -> "Forbidden"
404 -> "Not Found"
500 -> "Internal Server Error"
c if c >= 200 and c < 300 -> "Success"
c if c >= 400 and c < 500 -> "Client Error"
c if c >= 500 -> "Server Error"
_ -> "Unknown"
end
endJSON Navigation
lumen
cell get_string(json: Json, key: String) -> String | Null
match json
obj: map[String, Json] ->
match obj[key]
s: String -> s
_ -> null
end
_ -> null
end
endExpression Evaluator
lumen
enum Expr
Num(value: Float)
Add(left: Expr, right: Expr)
Sub(left: Expr, right: Expr)
Mul(left: Expr, right: Expr)
Div(left: Expr, right: Expr)
end
cell eval(expr: Expr) -> Float
match expr
Num(n) -> n
Add(l, r) -> eval(l) + eval(r)
Sub(l, r) -> eval(l) - eval(r)
Mul(l, r) -> eval(l) * eval(r)
Div(l, r) -> eval(l) / eval(r)
end
endBest Practices
- Order from specific to general — Put
_last - Use guards for complex conditions — Keep patterns simple
- Be exhaustive — Cover all cases or use
_ - Name bindings meaningfully —
xvsuser_id
Next Steps
- Declarations — Records, enums, cells
- Error Handling — Using result types