It Already Existed

Two probes in a row set out to force a missing feature and found it already built. Generic test assertions needed show to work through type variables — it did, silently, carried by the same machinery as the ordering episode. A flat early-return syntax for fallible pipelines needed inventing — it had shipped a dozen phases ago, documented, with five uses in an example. What the probes actually earned was three real defects hiding in the shadows of the features that existed: libraries that ran their demos on import, a flag the interpreter dropped, and a one-form inconsistency in the sugar itself.

meremethodergonomicstestinglanguage-design

Two of this part’s probes share a punchline, and it is at the method’s own expense. Both set out to force a feature into existence; both found the feature already there, functional and even documented. In a one-person project whose whole method is “measure, then build,” discovering twice in one week that the measuring happened after someone — the same person, months earlier — had already built the thing is funny, humbling, and worth an episode, because both probes still paid for themselves: each found real defects in the shadow of the feature that existed.

The test framework that was already generic

The first probe wanted a test framework whose assert_eq prints the failing values generically — the natural forcing program for show through type variables, the obvious sequel to the ordering episode. The ten-minute check came first: does show work through a type variable today? It does — on all four backends, carried by exactly the machinery the ordering episode described, made trustworthy by the same monomorphization fixes. And the framework? Also already there: a Test module in the standard library’s contrib area, with a generic assert_eq built on show, written a dozen phases earlier. The probe pivoted from building to verifying — assertions through a type-variable helper, failing values printed structurally, pinned into the suite. What it found instead was a hygiene defect: the library file carried its demo at the bottom, so every program that imported it ran the demo — noise, an intentional failure, someone else’s exit code. The demo moved out; the rule — library files are main-free — was applied across contrib, where five more libraries turned out to have the same flaw; and the same session caught the interpreter silently dropping the import search-path flag that the compilers honored, another of those interpreter/compiler asymmetries this project keeps finding at the CLI seam.

The syntax that was already flat

The second probe wrote an eight-step fallible config loader three ways to measure error-handling ergonomics. The nested-match pyramid was as bad as expected — seven levels deep, the same error-forwarding arm copied seven times, and the author miscounted the closing parentheses twice, which is a measurement too. The combinator chain was better but read inside-out. The probe’s design note sketched the fix: a binding form that unwraps a result or returns the error early. Then the docs grep that should have come first: the form exists. let x = e?! in body — and an option twin with ? — shipped a dozen phases ago, is documented with its own section in the patterns guide, and is used five times in the calculator example. Rewritten with it, the pipeline is a flat sequence of bindings, thirteen lines, no pyramid. The probe’s one real find: the ?/?! lets were the single let-form in the language that rejected ; as a substitute for in — every other let accepts both separators. Two parser lines closed the inconsistency.

The lesson, formalized

One “already existed” is an anecdote; two in a week is data about the method. The probes were designed to interrogate the runtime — grep the builtins, type the expression, run the program — because that is where capability gaps live. But features live one level up, in syntax and libraries, and the honest first step of any probe is now written into the project’s notes: grep the docs before writing the probe — the sugar list in the language reference, the patterns guide, contrib’s README table. There is a gentler reading, too. A language whose author repeatedly discovers it already does what they were about to add has crossed a small threshold: it has become bigger than the author’s working memory of it. That is what the documentation is for, and both probes left the documentation — and the seams around the features — better than they found them. The last two episodes return to things that genuinely did not exist: what happens when you type Japanese at the language, and what happens at a million elements.

← Back to Mere: Building a Language