Sum types & match
Model data with tagged unions and dispatch exhaustively with match.
An enum whose variants carry payloads is a tagged union (sum type): a value is exactly one
variant at a time, tracked by a hidden discriminant. This is the idiomatic way to model ASTs, IRs,
and state machines. Recursive shapes use a pointer.
enum Expr {
Lit(i64),
Add(Expr*, Expr*),
Neg(Expr*),
Nil // a unit variant (no payload)
} Constructing and matching
Construct with EnumName.Variant(args) (or just EnumName.Variant for unit variants). Dispatch with match, which binds each variant’s payload to fresh locals scoped to the arm.
fun eval(Expr* e) -> i64 {
Expr node
unsafe { node = ~e }
match node {
Lit(v) => return v
Add(l, r) => return eval(l) + eval(r)
Neg(x) => return 0 - eval(x)
Nil => return 0
}
return 0
} Rules
matchis exhaustive: cover every variant, or add a_arm.- A payload variant is laid out as an aggregate of a tag plus its payload, passed and returned by
value like a struct. Use a pointer (
Expr*) for recursive occurrences. - MVP payloads are scalars, pointers,
text, and enums up to 8 bytes each; wrap larger aggregates in a pointer. - Plain C-style enums (
enum Status : i32, no payloads) are unchanged. - An
exported sum type is fully usable across modules — importers can construct its variants andmatchon it.
Why it matters
Sum types make illegal states unrepresentable and pair with match to force you to handle every
case, all with zero runtime type information.
Next: Generics & slices.