Lyric
A statically typed application language with a bytecode VM — standalone, and embeddable in a host with a capability-based sandbox.
What changed in v4.4.0 — 2026-09-04
Pattern matching becomes complete. Two forms the grammar always admitted, the checker always accepted, and the lowering never built. Both are additive: every program that compiled before compiles unchanged, and the bytecode format is untouched.
Added
A
matchtakes a struct or a class apart.struct Point { x: int, y: int } fn sum(p: Point): int { return match (p) { Point { x, y } => x + y, }; }It tests nothing — the value is already of that type — so one arm covers the whole
match.Point { x = across }binds under a name of your own,_in a field's place skips the field, and a field left out is not read at all. A bound field is a copy, exactly aslet x = p.x;is.A field pattern only binds: writing a test into one (
Point { x = 3 }) is refused, and the refusal names the field it sits on.A
matchover an optional enum takes both states.fn area(s: ?Shape): int { return match (s) { null => -1, Shape.Dot => 0, Shape.Rect { w, h } => w * h, }; }Presence is settled before any variant is examined, because the tag lives inside the optional — and that changes nothing about which arm answers: the arms are tried in the order they were written, wherever the
nullarm stands among them.Before this, both forms failed at compile time with
LYR-IR0001. Nothing that worked has changed.