roadmap: iteration-discipline status + the it.3-surfaced blocking fork
it.1/it.2 shipped; it.2's D1 resolved the original two open spec
questions (same-family mutual rule; foldl=structural). it.3 BLOCKED
on a fundamental design-thesis gap: the totality story recognised
only ADT-structural recursion; the corpus sweep proved a second
canonical total scheme (Int-bounded well-founded recursion, incl.
branching build(d-1),build(d-1)) is overlooked and the milestone
as-specified makes it inexpressible — failing its own
feature-acceptance gate. Records the full option analysis with a
recommendation (A1: trichotomy + a documented non-negative-entry
obligation), flagged as a USER decision because it trades against
the purity pillar the user co-designed. Next: user decision →
it.2b → it.3 re-dispatch from c992eb9.
This commit is contained in:
+88
-21
@@ -40,10 +40,17 @@ clean. Pick the next milestone from P2.)_
|
|||||||
|
|
||||||
## P1 — Next
|
## P1 — Next
|
||||||
|
|
||||||
- [ ] **\[milestone\]** Iteration discipline — structural recursion +
|
- [~] **\[milestone\]** Iteration discipline — structural recursion +
|
||||||
named `loop`/`recur`; recursion-by-call restricted; `tail-app`
|
named `loop`/`recur`; recursion-by-call restricted; `tail-app`
|
||||||
retired. The iteration story of the language, decided in principle
|
retired. Spec `docs/specs/2026-05-15-iteration-discipline.md`
|
||||||
2026-05-15. Two constructs survive, one is removed:
|
(approved fda9b78; scope-corrected 2018178/10a0595). **Status
|
||||||
|
2026-05-15: it.1 SHIPPED (96db54d — loop/recur additive), it.2
|
||||||
|
SHIPPED (a4be1e5 — guardedness checker + first real Diverge
|
||||||
|
effect), it.3 BLOCKED on a surfaced fundamental design fork (see
|
||||||
|
"The blocking fork" below — needs a user design decision + a new
|
||||||
|
iteration it.2b before it.3 can re-dispatch).** The iteration
|
||||||
|
story of the language, decided in principle 2026-05-15. Two
|
||||||
|
constructs survive, one is removed:
|
||||||
- **Structural recursion stays — and becomes total-by-construction.**
|
- **Structural recursion stays — and becomes total-by-construction.**
|
||||||
A recursive call is permitted iff it is structurally guarded:
|
A recursive call is permitted iff it is structurally guarded:
|
||||||
each recursive call is on a constructor-smaller component of an
|
each recursive call is on a constructor-smaller component of an
|
||||||
@@ -85,30 +92,90 @@ clean. Pick the next milestone from P2.)_
|
|||||||
LLM-natural *and* their bug class is closed by construction; a bare
|
LLM-natural *and* their bug class is closed by construction; a bare
|
||||||
`while` is exactly what clause 3 rejects).
|
`while` is exactly what clause 3 rejects).
|
||||||
|
|
||||||
**The open spec question (the real brainstorm work).** Not "whether"
|
**Original open spec questions — RESOLVED in it.2 (a4be1e5).**
|
||||||
but the precise definition of "structurally smaller" / the
|
(1) *mutual* structural recursion → the conservative same-ADT-family
|
||||||
guardedness check. Two hard points: (1) *mutual* structural
|
rule (connected-components union-find over the type-reference
|
||||||
recursion (needs a measure / size over the ADT, not just a
|
graph; admits tree/forest, even/odd-over-Nat, mutual JSON; a
|
||||||
one-argument syntactic decrease); (2) the accumulator-carrying
|
general size-measure ordering stays out of scope). (2) the
|
||||||
structural walk — `foldl`-shaped, simultaneously structural *and*
|
`foldl`-shaped accumulator-carrying structural walk → **counts as
|
||||||
tail-shaped — the spec must decide whether it counts as structural
|
structural recursion** (plain, pure, total — only the structural
|
||||||
recursion (a plain call) or must be expressed as `loop`/`recur`.
|
argument must decrease; accumulator positions are unconstrained).
|
||||||
This is the load-bearing spec decision; brainstorm + grounding-check
|
Both shipped and pinned.
|
||||||
own it.
|
|
||||||
|
**The blocking fork (it.3-surfaced 2026-05-15 — needs a USER
|
||||||
|
design decision; touches the purity pillar the user co-designed).**
|
||||||
|
The milestone's totality thesis recognised exactly ONE
|
||||||
|
total-by-construction recursion scheme: structural-over-an-acyclic-
|
||||||
|
ADT (Decision 10). The it.3 mandated corpus sweep proved this is
|
||||||
|
*incomplete*. Six corpus fixtures contain the single most
|
||||||
|
LLM-natural tree-builder shape:
|
||||||
|
`build(d: Int) = if d==0 then Leaf else Node(1, build(d-1), build(d-1))`.
|
||||||
|
It is provably terminating, but: **not** ADT-structural (`d` is
|
||||||
|
`Int`, no constructor-smaller component) and **not** `loop`/`recur`-
|
||||||
|
able (it is *branching/double* recursion; `recur` is a single
|
||||||
|
tail-position back-edge — a balanced-tree build is not a tail
|
||||||
|
loop; the only `loop` form is a hand-rolled explicit-stack
|
||||||
|
worklist, which no LLM writes). So the milestone *as-specified*
|
||||||
|
makes a trivially-total, maximally-natural function
|
||||||
|
**inexpressible** — failing its own feature-acceptance criterion
|
||||||
|
(clause 1: the LLM reaches for `build(d-1),build(d-1)`; clause 2:
|
||||||
|
the milestone would *remove* expressivity). This is a real
|
||||||
|
design-thesis gap, not a migration nuisance: there is a SECOND
|
||||||
|
canonical total-by-construction scheme the design overlooked —
|
||||||
|
**well-founded recursion on a strictly-decreasing non-negative
|
||||||
|
integer measure** (`f(0)=base; f(n)=…f(n-1)…`, branching allowed).
|
||||||
|
|
||||||
|
**Decision the user must make** (it trades against the purity
|
||||||
|
pillar — Int ≠ ℕ; AILang has no `Nat`/refinement types, so
|
||||||
|
Int-bounded recursion is total only for *non-negative entry*):
|
||||||
|
- **A1 (RECOMMENDED).** Make the totality story a *trichotomy*:
|
||||||
|
ADT-structural | Int-bounded-well-founded | explicit `loop`/`recur`.
|
||||||
|
Accept Int-bounded recursion (recursive call on `p - <pos-lit>`
|
||||||
|
with a non-recursing base guard, branching allowed) as a
|
||||||
|
*second total-by-construction class*, with one documented
|
||||||
|
obligation: non-negative entry (a negative seed diverges — the
|
||||||
|
same precondition class as array-bounds the language already
|
||||||
|
lives with). Restores the entire `f(n-1)` recursion family (the
|
||||||
|
second-most-common shape in any corpus); keeps all 6 fixtures
|
||||||
|
verbatim; the trichotomy is *more* complete, not less principled.
|
||||||
|
Rationale is the language's own gate: a milestone that makes
|
||||||
|
`build(d)` inexpressible cannot pass the feature-acceptance
|
||||||
|
criterion. *Why this is a user call:* it concedes "total by
|
||||||
|
construction, sign nothing" → "total by construction modulo one
|
||||||
|
documented non-negative-entry obligation" — a dilution of a
|
||||||
|
purity pillar the user personally weighted in the original
|
||||||
|
Socratic design dialogue.
|
||||||
|
- **A2.** Introduce a `Nat` type; accept Int-bounded recursion
|
||||||
|
only on `Nat` — preserves zero-precondition purity, but `Nat`
|
||||||
|
is its own sub-milestone and an LLM writes `depth: Int` unless
|
||||||
|
the prelude makes `Nat` the natural default (clause-1 friction).
|
||||||
|
- **A3 / B / C (not recommended).** Strict-dichotomy +
|
||||||
|
explicit-worklist (fails clause 1 — no LLM hand-rolls a stack
|
||||||
|
for tree-build); a narrow carve-out predicate (the patch smell);
|
||||||
|
reshaping the LLM-natural fixtures (forbidden —
|
||||||
|
`feedback_dont_adapt_tests_to_bugs`).
|
||||||
|
|
||||||
|
**If A1 (or A2): new iteration it.2b** — additive widening of the
|
||||||
|
it.2 guardedness checker to also accept Int-bounded (incl.
|
||||||
|
branching) recursion as total; no removal. After it.2b the 6
|
||||||
|
fixtures check clean with zero migration; it.3 then re-dispatches
|
||||||
|
from c992eb9 (the `bench/it3-oracle/` 40-fixture behavioural
|
||||||
|
oracle is preserved and reused; nothing in it.3 was destructive).
|
||||||
|
The it.3 RC-RSS/18g.1 load-bearing risk (Task 5.5/5b) is still
|
||||||
|
UNTESTED — must not be treated as resolved by the milestone-close
|
||||||
|
audit.
|
||||||
|
|
||||||
**Relation to Stateful islands.** This entry owns the iteration
|
**Relation to Stateful islands.** This entry owns the iteration
|
||||||
story and *supersedes* the "while-loops legal" scope bullet of the
|
story and *supersedes* the "while-loops legal" scope bullet of the
|
||||||
Stateful-islands milestone below. The genuinely-escaping
|
Stateful-islands milestone below. The genuinely-escaping
|
||||||
mutable-state path (`ref a` / `MutArray a` / `Stateful a b` /
|
mutable-state path (`ref a` / `MutArray a` / `Stateful a b` /
|
||||||
`pipe`) is unaffected and stays in Stateful-islands — that is the
|
`pipe`) is unaffected and stays in Stateful-islands.
|
||||||
deliberately-fenced streaming escape hatch for *escaping* state,
|
|
||||||
not the default iteration story, and F1 no longer motivates it.
|
|
||||||
|
|
||||||
- context: 2026-05-15 chat — design convergence from the
|
- context: spec `docs/specs/2026-05-15-iteration-discipline.md`;
|
||||||
mut-local fieldtest (F1) through the fenced-`while` /
|
per-iter journals 2026-05-15-iter-it.1 (shipped), -it.2
|
||||||
`!Mut`-visibility dead end to the structural-recursion +
|
(shipped), -it.3 (BLOCKED — the design fork above). Next action
|
||||||
named-loop synthesis. Pending brainstorm produces
|
is a USER decision on the blocking fork (A1 recommended), then
|
||||||
`docs/specs/<date>-iteration-discipline.md`.
|
iteration it.2b, then it.3 re-dispatch from c992eb9.
|
||||||
|
|
||||||
- [x] **\[milestone\]** Heap-`Str` ABI — runtime infrastructure for
|
- [x] **\[milestone\]** Heap-`Str` ABI — runtime infrastructure for
|
||||||
malloc-backed, refcounted `Str` values alongside the existing
|
malloc-backed, refcounted `Str` values alongside the existing
|
||||||
|
|||||||
Reference in New Issue
Block a user