Last pass found a population column counting comments: sign published as 63 uses in 48 specs is 1 use in 1 spec, and that 63 had already become a recommendation to treat it as a language-level question. The obvious response is to re-count every figure this campaign has published.
Doing so found something else.
Almost none of the movement was miscounting
| figure |
published |
re-derived in code |
why it differs |
cast_i8 uses |
1079 |
1079 |
— |
[]T{} empty slice literals |
478 |
478 |
— |
abs( uses |
389 |
389 |
— |
x.len() |
1322 |
1319 |
3 in comments |
x.len |
687 |
680 |
7 in comments |
| three-segment paths |
477 |
473 |
4 in comments |
len(x) |
"142" |
296 |
142 was a DIAGNOSTIC count in the generated C, not a spec population |
pub const OP_* |
"20" |
11 |
20 was a count of LIST SITES in the C, not of declarations |
[T] |
220 |
220 or 228 |
depends on which names count as a type — float and int add 8 |
Comments cost between 3 and 7 on three figures. The two large discrepancies are unit conflations: a sentence about the specs quoting a number measured in the generated C. And [T] moves by which primitive set the matcher used — a number that cannot be reproduced without it.
What that implies
A number without its matcher is not reproducible. A number whose unit is implicit is not comparable. Re-counting is not enough; the matcher and the unit have to travel with the figure.
What ships
tools/published_figures.py pins each figure with the regex that produced it and the unit it is in, re-derives them all from the specs in code only, and --check exits 1 on drift — the same contract the census pin already has in this repository: a change that moves a number must say so.
It caught one on its first run: test blocks 12 644 → 12 456. The corpus moved, and the explanation is on the record — #3482 deleted 188 duplicate blocks whose bodies were byte-identical to their twin, and 12 644 − 188 = 12 456. The pin followed the corpus rather than being blessed away.
Wired into Spec Guards beside the duplicate-declaration ratchet, with the paths: filter extended so a change to the file triggers the workflow that reads it. A positive control is recorded: with a deliberately wrong pin the gate exits 1 and names the drifting row; restored, it exits 0.
The corrections this publishes
Last pass found a population column counting comments:
signpublished as 63 uses in 48 specs is 1 use in 1 spec, and that 63 had already become a recommendation to treat it as a language-level question. The obvious response is to re-count every figure this campaign has published.Doing so found something else.
Almost none of the movement was miscounting
cast_i8uses[]T{}empty slice literalsabs(usesx.len()x.lenlen(x)pub const OP_*[T]floatandintadd 8Comments cost between 3 and 7 on three figures. The two large discrepancies are unit conflations: a sentence about the specs quoting a number measured in the generated C. And
[T]moves by which primitive set the matcher used — a number that cannot be reproduced without it.What that implies
A number without its matcher is not reproducible. A number whose unit is implicit is not comparable. Re-counting is not enough; the matcher and the unit have to travel with the figure.
What ships
tools/published_figures.pypins each figure with the regex that produced it and the unit it is in, re-derives them all from the specs in code only, and--checkexits 1 on drift — the same contract the census pin already has in this repository: a change that moves a number must say so.It caught one on its first run: test blocks 12 644 → 12 456. The corpus moved, and the explanation is on the record — #3482 deleted 188 duplicate blocks whose bodies were byte-identical to their twin, and 12 644 − 188 = 12 456. The pin followed the corpus rather than being blessed away.
Wired into Spec Guards beside the duplicate-declaration ratchet, with the
paths:filter extended so a change to the file triggers the workflow that reads it. A positive control is recorded: with a deliberately wrong pin the gate exits 1 and names the drifting row; restored, it exits 0.The corrections this publishes
x.len()1319, not 1322;x.len680, not 687; three-segment paths 473, not 477.len(x)spelling is 296 uses in 29 specs. The 142 quoted in gen-c:s.lenon a string is strlen(s) -- the decidable third of the len family #3489 was the number ofcall to undeclared function 'len'diagnostics, which is a different population and was described as if it were the same one.pub const OP_*declarations are 11, in one spec. The 20 quoted in gen-c: cast_iN(x) is a cast, not a call -- Zig has lowered it since W570 and its comment names the blocker #3497 was the number of list sites in the generated C that referred to them.