Files
AILang/docs/journals/2026-05-18-iter-prose-loop-binders.1.md
T
Brummel c9355d7d58 iter prose-loop-binders.1: Form-B loop binders as parenthesised init-list
The Term::Loop arm of write_term rendered binders as bare
`name = init;` statements inside the `loop { … }` body block, which
reads as C/Rust re-init-every-iteration semantics — a projection
lying about a body the prose surface exists to let the reader trust.
Rewrite to a parenthesised init-list on the keyword line,
`loop(acc = 0, i = 1) { … }`, positionally isomorphic to the
unchanged Term::Recur arm. Projection-only: loop/recur AST, Form-A,
JSON-AST, typecheck, codegen, and the Form-A↔JSON round-trip
invariant untouched. RED-first via two new committed
examples/*.prose.txt byte-equality snapshots + two snapshot_loop_*
tests; full ailang-prose suite 10/0; both ail-prose CLI byte-matches
green. Single-iteration milestone, brainstorm→plan→implement.

Spec: docs/specs/2026-05-18-prose-loop-binders.md
Plan: docs/plans/prose-loop-binders.1.md
2026-05-18 01:04:19 +02:00

2.9 KiB

iter prose-loop-binders.1 — Form-B loop renders binders as a parenthesised init-list on the keyword

Date: 2026-05-18 Started from: 6533134dab Status: DONE Tasks completed: 2 of 2

Summary

Projection-only single-iteration milestone in ailang-prose. The Term::Loop arm of write_term (crates/ailang-prose/src/lib.rs) now renders loop binders as a parenthesised init-list on the keyword line — loop(acc = 0, i = 1) { … } — instead of bare name = init; statements inside the body block. The old shape implied C/Rust re-init-every-iteration semantics; the new shape mirrors the adjacent (untouched) Term::Recur arm's enumerate() + ", "-separator idiom and renders init expressions at level (they sit on the keyword line, not the indented block). RED-first: two committed examples/*.prose.txt snapshot fixtures plus two check_snapshot-calling #[test] fns were added and verified failing against the old renderer before the arm rewrite made them pass. Loop/recur AST, Form-A, JSON-AST, typecheck, codegen and the Form-A↔JSON round-trip invariant are untouched by construction (single render-arm body rewrite, no signature change, no caller touched).

Per-task notes

  • iter prose-loop-binders.1.1: RED — created examples/loop_sum_to_run.prose.txt (multi-binder + non-recur exit) and examples/loop_forever_build.prose.txt (single-binder recur-only) with the exact Option-A bytes from the plan; appended snapshot_loop_sum_to_run + snapshot_loop_forever_build after snapshot_ordering_match in tests/snapshot.rs. cargo test -p ailang-prose snapshot_loop0 passed; 2 failed; 8 filtered out (filter resolved to exactly the two new tests; both panic with the expected prose snapshot mismatch message). RED confirmed.
  • iter prose-loop-binders.1.2: GREEN — rewrote the Term::Loop arm at lib.rs:938-955 verbatim per the plan (parenthesised init-list, init at level, stale "not yet designed" comment removed). cargo test -p ailang-prose snapshot_loop2 passed; 0 failed; full ailang-prose suite → 10 passed; 0 failed (no pre-existing snapshot regressed); both ail prose | diff CLI byte-matches → MATCH; post-cleanup git status --porcelain is EXACTLY the four expected paths.

Concerns

(none)

Known debt

(none — projection-only single-arm rewrite, fully gated by whole-file byte-equality snapshots + live-CLI diff)

Files touched

  • crates/ailang-prose/src/lib.rsTerm::Loop arm of write_term rewritten (single hunk, lines 938-953)
  • crates/ailang-prose/tests/snapshot.rs — two #[test] fns appended after snapshot_ordering_match
  • examples/loop_sum_to_run.prose.txt — new committed snapshot
  • examples/loop_forever_build.prose.txt — new committed snapshot

Blocked detail

(n/a — Status DONE)

Stats

bench/orchestrator-stats/2026-05-18-iter-prose-loop-binders.1.json