print-str, print-i64, print-f64, print-bytes, print-line and newline leave
the prelude. print and println are the whole printing surface now, and print
is the better call at every one of the sites that used them: it is the same
structural walk without the newline, so the no-newline case the family was
kept for is covered, and it takes the value as it is. The old print-i64
forced an explicit (i64 x) at every call site, because this language widens
nothing implicitly; that cast is gone from 127 places.
Dropping it moves one answer. hash-grid returns u64, and the cast through
the signed printer showed sand-headless's hash as -2851001042534928384.
print routes a u64 through flan_u64_to_bytes, so it now prints
15595743031174623232 — the same 64 bits, read as the unsigned number they
are. The pinned expectation follows the correction.
test-flan-dev.el and test_session.ml both reached for print-line as "a name
the prelude has"; they reach for rand-seed instead.
Two claims in these comments were stronger than the permutation runs
behind them. The WAV round trip catches sample-size against channels
and leaves frame-count against sample-rate entirely green — the crop
and the reformat are what catch that pair, and a reader who trusted the
round trip would drop exactly the wrong case. The font file listed what
it pins and never said that glyph-padding, offset-y and three of each
atlas rectangle's four fields are read by nothing here at all.
Two more permutations run and recorded while fixing it: GlyphInfo's
image moved to the front, which shifts the four ints 24 bytes and
collapses the glyph search, and Rectangle's x with width, which moves
"measure ABC" to 39 and confirms the advance-0 fallback is the only
thing reading a width out of the recs array.
Audio was written off as needing a device. That is true of Sound and
Music and false of Wave: copy, crop, reformat, export, load and decode
are all CPU work, and wave-format is the same scalars-in/fields-out
shape gen-image-color is, with the frame count computed rather than
handed over. Cropping to a single frame before decoding puts raylib's
byte-offset arithmetic in front of the decoder, which is what tells
sample-size from channels — an axis discriminator, not a mirror.
Fonts were said to have no headless test. They do, once the program
stops asking raylib for a font and builds one out of Flan arrays: text
measuring reads every field and computes. Both cases were verified red
by permuting the defstructs; the permutations are recorded in the
comments so the next reader need not rediscover which ones bite.