Conversation
…onstruct)
`fold` is now a thin imperative sugar over `for`:
fold <acc> = <init> for <clauses> { body }
==> { var <acc> = init; for <clauses> { body }; <acc> }
The accumulator is a real mutable var, ASSIGNED in the body (`acc = f(acc,x)` /
`acc += x`), not yielded as the tail value; the whole-fold value is the
accumulator after the loop. Multiple accumulators are multiple vars
(`fold a=0, b=1 for ..`). break/continue/return are legal in the body (it is a
plain `for`). A closure in the body captures the accumulator VAR. The named
reduction sugars (all/exists/count/find/find_opt/filter/vector, spelled
`name(for ...)`) are a separate construct, unchanged.
Highlights (full history in docs/fold1_report.md):
- Simultaneous tuple assignment `(a,b) = (b,a+b)`: a parse-time desugar
(materialize RHS into a temp before any store) — the Fibonacci/swap idiom.
- FB-023 fixed: a latent C-gen soundness hole (single-use temp reading mutable
memory inlined past an aliasing store), surfaced by the swap; fixed with a
recursive movement_unsafe_read guard in find_single_use_vals.
- Token-precise spans: the reform-prep-1 batch spans now give each token its own
span; a side win is 12 negative goldens with tighter, correct carets.
- The whole 68K-line corpus AND the self-hosting compiler migrated to the new
form (census docs/fold_census.md: 261 sites, zero closure-captures-accumulator
sites, so the var-capture semantics change is behavior-neutral). Compiler
migration handled a silent-bug class where an accumulator name shadows its own
iteration collection / a body val — every such site renames the accumulator.
- An old-style value body warns "'fold' accumulator 's' is never assigned … the
body must UPDATE the accumulator ('s = <expr>' / 's += ...')".
Verification: full ladder green (unit 168, negative 90, T4 IR 63, cfold, corpus
O0/O3); bootstrap fixpoint holds (the compiler self-builds deterministically
after migrating its own folds); -pr-resolve census unaffected.
CLAUDE.md fold gotcha rewritten; language_changes_brief.md §2 -> IMPLEMENTED.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
foldis now a thin imperative sugar overfor:The accumulator is a real mutable var, ASSIGNED in the body (
acc = f(acc,x)/acc += x), not yielded as the tail value; the whole-fold value is the accumulator after the loop. Multiple accumulators are multiple vars (fold a=0, b=1 for ..). break/continue/return are legal in the body (it is a plainfor). A closure in the body captures the accumulator VAR. The named reduction sugars (all/exists/count/find/find_opt/filter/vector, spelledname(for ...)) are a separate construct, unchanged.Highlights (full history in docs/fold1_report.md):
(a,b) = (b,a+b): a parse-time desugar (materialize RHS into a temp before any store) — the Fibonacci/swap idiom.Verification: full ladder green (unit 168, negative 90, T4 IR 63, cfold, corpus O0/O3); bootstrap fixpoint holds (the compiler self-builds deterministically after migrating its own folds); -pr-resolve census unaffected.
CLAUDE.md fold gotcha rewritten; language_changes_brief.md §2 -> IMPLEMENTED.