The Classics Quartet

Four textbook programs thrown at the language in one sitting, each aimed at a suspected soft spot: matrix multiplication at nested containers, Game of Life at generation updates, Sudoku at mutate-and-undo backtracking, and a digit-vector factorial at the fixed-width integer. All four came out correct on both native backends, first try, zero new bugs. After twenty-six releases of probe-driven fixes, a day when nothing falls over is not a wasted probe — it is the measurement the whole method was working toward, and it gets recorded like any other.

mereexamplesmethodtestinglanguage-design

Every probe so far in this series was aimed at something suspected to be broken, and most of them hit. This last episode of the part inverts the bet: four classic programs, chosen precisely because each leans on a subsystem that recent work made suspicious, run in one sitting to see what falls over. Matrix multiplication leans on nested containers (Vec[Vec[float]]) and the copy-on-store semantics underneath them. Game of Life leans on read-the-current-generation-while-writing-the-next. Sudoku leans on mutate-and-undo — a backtracking solver that writes a digit, recurses, and must trust that undoing the write actually undoes it. And a big-number factorial leans, on purpose, on the one thing the integer story explicitly does not give you: arbitrary precision.

Four programs, zero bugs

All four came out correct, on the interpreter and the C backend, on the first run. The matrix product is exact. The glider translates one cell diagonally every four generations, and after eight sits exactly where Conway says it should, five cells and no debris. The 9×9 puzzle solves to the known unique solution. And the factorial episode is the fixed-width story told honestly in two acts: native 21! wraps to the same negative number on both backends — the same wrap, identically, which is itself a small victory for the width unification of two parts ago — and then thirty-three digits of 30! come out of a vector of digits, correct to the last zero. Zero new bugs, in the four places most likely to have them. After twenty-six releases of finding-and-fixing, that is not a boring result. It is the measurement the method was always pointing at: the language’s tested surface has grown past the size of a textbook chapter. The quartet joins the examples directory — one of them under a new name, because a Game of Life already existed as the syntax-sugar showcase, and overwriting history with a probe would have been its own small bug.

The one pain, and the part’s ledger

One thing did hurt, and it was a message, not a semantics. The matrix code reads cells through a small polymorphic helper, and at the moment the type checker sees `s + get a i

  • get b j, the helper's element type is still an unresolved variable — so the numeric operators default to int, and the eventual "expected float, got int" error points at an innocent expression far from the real cause. The defaulting rule itself stays (it was weighed and documented two parts ago); what changed is that the error now *explains itself* — the hint names the defaulting, and offers both escapes: annotate a parameter, or ascribe one operand. The part's ledger, then: channels learned to close, supervisors learned to give up, select` turned out to be unnecessary, a capture-analysis bug died in a pub/sub broker, and four classics ran clean. The ending toolkit exists because three small programs demanded it; the quartet says the rest of the foundation is holding. What the next part measures is, as always, not yet decided — the probes will pick.
← Back to Mere: Building a Language