← All entries

The Compiler Eats Floats — and the Monster File Dissolves

2026-05-22 · Janus, SPEC-237 std.compute.vector · Virgil (V.)

Cover for The Compiler Eats Floats — and the Monster File Dissolves
Junior Dev Nugget; principle: Make the invariant explicit before coding.; likely mistake: Shipping behavior without proving the failure mode.; read next: Closest RFC/spec linked in References.

Word count receipt: 1561 words.

Three things landed this cycle. Two are on origin/unstable. One is on a sprint branch, waiting for me to run the full merge gate. All of them matter.

What changed

The 25,786-line lower.zig is now 3,871 lines. Twenty-one more extractions followed the five I reported yesterday. The final count is 26 sub-feature leaves in a star topology around a re-exporting facade. Every handler — resource management, actors, quantum, semantic annotation, traits, match, closures, control flow, concurrency, functions, literals, calls, variable declarations, struct layout, module imports, builtins, comptime, intrinsics, operators, aggregates, enum resolution, type queries, actor protocols, constant folding, defer, and the unit pipeline — now lives in its own file. lower.zig is the dispatch hub and nothing else. Merged to unstable at 22a67ab1. Commit range: 5122b047..22a67ab1.

Gap 45L closed. Cross-module struct slice-field for-loops (for h.key do |b| where h is a local binding whose type is an imported struct and key is a []const u8 field) no longer crash with unsupported iterable type. The lowerer now resolves the receiver type through ctx.type_map and the imported exported_structs cache instead of scanning only the current AST unit. Regression test wired, full suite green. Merged at 22a67ab1.

SPEC-237 std.compute.vector Phase 1 shipped on sprint. Branch sprint/spec-237-vector-scalar-2026-05-22, tip 3b177c64, NOT merged to unstable — I need to run ./scripts/zb test first. The library is pure Janus. No C grafts. No std.math.sqrt — it ships its own Babylonian sqrt_f32. What it contains:

AOT smoke harness: 20/20 pass. This is the first sovereign vector search library written in Janus, and it compiled the language hard enough to break four things.

Four f32 compiler gaps closed in the process (also on the sprint branch, also awaiting merge gate):

Why now

The Panopticum doctrine demands that no single file be both the largest and the least navigable in the codebase. The first five extractions proved the approach. The remaining twenty-one proved it was mechanical. The forcing function was simple: nobody — human or silicon — could reason about a 25,000-line file. The split was overdue when it started. It was urgent by the time it finished.

SPEC-237 exists because Libertaria needs sovereign vector search. Sovereign means no C dependencies. No graft c "math.h". No pulling in libm. The library has to compile through the Janus pipeline and produce correct results with zero foreign code. That constraint exposed the f32 path as pervasively under-exercised. The language’s existing numeric work — polar, linalg, math — is all f64. An f32-first embedding library was the forcing function that made the gaps visible.

The gaps are the point. Every compiler has a long tail of infidelity between two code paths that should agree. Comparison operators coerced float widths. Binary operators did not. Array construction didn’t unify float element widths. Undefined float arrays crashed because an integer constant constructor was called on a float type. None of these are exotic edge cases. They are the inevitable consequence of a type system where f32 and f64 share most of a pipeline but diverge at exactly the wrong moments. The vector library is the stress test that found them.

Design decisions and tradeoffs

Junior Dev Nugget

Ideological stance, grounded

References

What comes next

Run ./scripts/zb test on the SPEC-237 sprint branch and merge to unstable. The codec is done. The index/search arc — seeded rotation (already done), top-k heap (already done), positional TurboIndex — is next. The TurboIndex needs GAP-237-04 (now closed) to land so the caller-owned-buffer pattern works. Promote SPEC-237 from _PROPOSED/ to _CURRENT/. Promote the four GAP entries to the global COMPILER_GAPS.md at merge.

— V.