Skip to content

Retire the reg and Recurse names, and pin the out-of-block read rule - #106

Open
dpmills wants to merge 4 commits into
dmills/per-key-completionfrom
dmills/mutability-vocab-cleanup
Open

Retire the reg and Recurse names, and pin the out-of-block read rule#106
dpmills wants to merge 4 commits into
dmills/per-key-completionfrom
dmills/mutability-vocab-cleanup

Conversation

@dpmills

@dpmills dpmills commented Aug 18, 2026

Copy link
Copy Markdown
Contributor

The mutability subsystem renamed its concept to "mutable variable", but the identifiers carrying it still said register — the fresh name was __reg, a key's history binding was reg_k, locals were reg_read / reg_vtys — and __reg reaches symbolic output and test assertions, so the old word outlived the rename exactly where a reader meets it. This retires it (the record is __hist, its fields hist_k, and the prose calls it a history record) along with a second name in the same state: Recurse, the removed recurrence operator behind an induction accumulator, still cited in twenty-five comments across thirteen files as though it were something to go look at. Each of those names what it now means, since the old one stood for the induction-store engine in some places and a loop's own cycle in others.

The out-of-block read is a rule, not a caution

mutability.md presented the non-atomic pre-check if balance > 0: with begin(): balance -= req as compilable but unwise, and asked for a lint. The guard reads a Txn variable outside a block, which lowering rejects and always will, so the shape does not compile and there is nothing to lint; the spec's reads bullet is marked [Decided] to match. The rule had no test where it is easiest to lose — following a Mut(_, Txn) parameter into a callee — and now has one.

Prose

mutability.md also drops the voice its own rules call out: stress-italicised copulas and negations throughout, deliberately seven times, Footgun as a heading, and strict wall for the strict typecheck, a metaphor already colliding with two other mechanisms.

@dpmills

dpmills commented Aug 18, 2026

Copy link
Copy Markdown
Contributor Author

@dpmills dpmills changed the title Rename __reg to __hist and convert mutability.md to specification prose Retire the register vocabulary and mutability.md's stale framing Aug 18, 2026
@dpmills dpmills changed the title Retire the register vocabulary and mutability.md's stale framing Retire the "reg" vocabulary and mutability.md's stale framing Aug 18, 2026
@dpmills
dpmills force-pushed the dmills/mutability-vocab-cleanup branch from f23af7d to 7b0f83b Compare August 18, 2026 21:13
@dpmills dpmills changed the title Retire the "reg" vocabulary and mutability.md's stale framing Retire the reg and Recurse names, and pin the out-of-block read rule Aug 18, 2026
@dpmills
dpmills force-pushed the dmills/mutability-vocab-cleanup branch 2 times, most recently from 9e042ba to 1680307 Compare August 19, 2026 18:34
@dpmills
dpmills force-pushed the dmills/mutability-vocab-cleanup branch 2 times, most recently from 9a01394 to f671a4f Compare August 19, 2026 18:54
@dpmills
dpmills marked this pull request as ready for review August 20, 2026 00:44
@dpmills
dpmills requested a review from a team as a code owner August 20, 2026 00:44
The mutability subsystem renamed its concept to "mutable variable", but the
identifiers that carry it still said register: `Name::fresh("__hist")` was
`__reg`, the notation for a key's history binding was `reg_k`, and locals were
`reg_read` / `reg_vtys`. Since `__reg` reaches symbolic output and test
assertions, the term outlived the rename everywhere a reader actually meets it.
The record's fields are the per-key history bindings, so it is `__hist`, its
fields are `hist_k`, and the prose calls it a **history record** rather than a
mutable variable record — one name for one thing.

Two prose sites kept the old word outright (`mutability.md` on what a `Let` may
bind, `transact_phase` on a block-local declaration).

`mutability.md` also loses the voice the prose rules call out: 30 stress-italicised
copulas and negations, `deliberately` six times, `Footgun` as a heading, and
`strict wall` for the strict `typecheck` — the metaphor the `spec-prose` skill
names as having collided with two other mechanisms. Where the stress marked a real
contrast the contrast is now in words. The `Liveness` bullet stated the as-of /
terminal split a third time and now points at the section that owns it.

`wall` survives in `channelize.rs` and `infer/check.rs`, which are a different
subsystem's prose.
`mutability.md` presented the non-atomic pre-check `if balance > 0: with begin():
balance -= req` as compilable but unwise — "faithfully compilable (the guard
becomes a gating as-of read)" — and asked for a lint. That misreads the rule: the
guard reads a `Txn` variable outside a block, which lowering rejects and always
will, so the shape does not compile and the atomic form is the only way to write
the check. Nothing to lint, and the section says so.

The CHL spec's reads bullet is marked `[Decided]` to match, and points at the two
terms that read without a snapshot rather than leaving "an error" to look
provisional.

A rule this load-bearing should be pinned where it is easiest to lose: the gate
follows a `Mut(_, Txn)` parameter into a callee, since a by-reference pass hands
it a mutable variable in its own right. That had no test.
`Recurse` was the dense recurrence operator behind an induction accumulator. It
is gone — the changelog `InductionStore` and its drive replaced it — but twenty
comments across three directories still cite it, in backticks, as though it were
something a reader could go look at. Nothing catches that: `./ci.sh doc_refs`
validates doc paths and headings, so a renamed *heading* fails the build, while a
backticked type name in prose is unchecked. One deleted operator was enough to
accumulate twenty of them.

Each site names what it actually means now rather than taking a blanket
substitution, because the old name stood for three different things depending on
where it was written: the induction-store engine a causal self-cycle is
recognized onto (`ops.rs`, `operator_conversion.rs`, `mut_elim.rs`,
`lower/transactions.rs`, `planning/iterate.rs`), a loop's store/drive cycle and
its one-position-per-pull rate (`cli_driver_convergence.rs`, `helpers.rs`,
`transactions.rs`), and a `.writes`-cycling realization whose correctness rests on
carry-completeness (`mut_elim.rs`, `sources_incremental.rs`).

Four of them carried a comparison to how the removed operator behaved — a bug it
had, an ordering it scrambled, a projection it produced. A reader cannot check any
of that against the code in front of them, so each now states the property that
holds instead. `sources_incremental.rs` also had two doc comments merged into one,
leaving a sentence that ends at "but exercising `Recurse` instead of" and then
describes a different test; the orphaned lead-in goes.

`src/interpreter/CLAUDE.md` has the last two and is deliberately not touched here.
Its stale example is `Recurse::recursive_input_setter` for constructor-time
wiring, and the replacement is `CycleSlot`, which arrives lower in the stack —
where the contradiction is with that branch's own new guidance.
An earlier pass replaced the word `register` by string, so it hit the ordinary
verb too: `if the program mutable variables any sinks`, `still mutable variable
nothing`, `and mutable variables rhs (α)`, `` outer's body mutable variables a
nested `Mut`-param bump ``. Eleven sites read as nonsense. The verb is restored
at each; the sentence around it is unchanged, so these lines match their
pre-rename text.

The same pass left the noun behind where the rename was the point. A
variant-valued mutable variable was still a `register` throughout its test's doc
comment and in the test's own name; a `Let` `cannot bind a register at all`; `an
alias means a register with an unknown writer set`. The identifiers `reg` (the
awaited variable's `Name`, six sites), `reg_ty` (the history record's type, which
`plan_store` already calls `hist_ty`), and the `reg_k` notation went the same way.

`n_reg` in the commit and induction stores becomes `n_carry`: it counts the carry
write keys against the tap keys, which is the split the comment beside it states,
and nothing about it was ever the variable.
@dpmills
dpmills force-pushed the dmills/mutability-vocab-cleanup branch from cafecd9 to 85ace0a Compare August 20, 2026 18:47
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant