Enums, Unions & Patterns
Jiang separates finite tag sets from payload-bearing sum types:
enumdefines named members.uniondefines a safe tagged union where variants may carry payloads.
enum Mode { read, write,}
Mode mode = Mode.read;Mode other = .write;Members may specify values:
enum Priority { low = 1, medium, high,}Enum discriminants use Int32 by default. Convert an enum value with a target integer
constructor such as Int(value) or UInt8(value); enum cases do not expose a .value
member.
Use enum [UInt8] or another integer type when the stored representation must be
fixed:
enum [UInt8] ByteTag { block = 1, item,}
UInt8 tag = UInt8(ByteTag.block);Convert an enum value with a target integer constructor:
Int value = Int(Mode.read);Unions
Section titled “Unions”union Outcome<T, E> { T ok; E err;}
Outcome<Int, ParseErr> a = Outcome.ok(42);Outcome<Int, ParseErr> b = .err(ParseErr.bad);Same-type variants can be grouped:
union Value { Int int_value, code; Double float_value; UInt8[]& text;}Unions can bind an explicit tag enum:
enum Kind { int_value, text,}
union [Kind] TaggedValue { Int int_value; UInt8[]& text;}if value is .int_value(_ n) { print(n);} else { print(0);}Put ! after the name for a mutable inferred binding:
if value is .int_value(_ n!) { n = n + 1;}Use ref T name to borrow a union payload instead of binding it by value:
union Node { (Int, Int) pair; () empty;}
Int read_ref(Int& value) { value$.get()}
Int first(Node node) { if node is .pair(ref Int left, _) { return read_ref(left); } return 0;}This matters when the payload is large, non-copyable, or should be inspected without moving it.
In patterns, ref! Int value creates a unique mutable Int&! borrow. Write ref Int value! or
ref! Int value! when the resulting reference binding itself must be reassignable.
Optional values use .some(...) and .none:
if maybe is .some(payload) { print(payload);} else { print(0);}switch
Section titled “switch”Int code = switch mode { .read => 1, .write => 2,}Union payloads:
Int result = switch value { .int_value(_ n) => n, .code(_ code) => code, .float_value(_) => 0, .text(_ bytes) => bytes.length,}Borrowed union payloads use the same ref sub-pattern:
Int result = switch node { .pair(ref Int left, _) => read_ref(left), .empty => 0,}Optional values:
Int value = switch maybe { .some(payload) => payload, .none => 0,}Pattern Roots
Section titled “Pattern Roots”is and switch branch roots accept:
- optional patterns:
.some(payload)and.none - variant patterns:
.name(...)orType.name(...) - literal patterns such as
null, numbers, chars, and booleans
Bindings and wildcards are sub-patterns of optional or variant payloads. Tuple patterns are not switch roots; use destructuring statements for tuples.