Files
AILang/examples/fieldtest/remove-mut_4_bracket_scanner.ail
T
Brummel 5bb721178f fieldtest: remove-mut-var-assign — 4 examples, all working; milestone CLOSED
Post-audit downstream-LLM-author field test of the post-removal
Form-A surface. 4 fresh real-world programs written from DESIGN.md +
form_a.md + public examples only (no compiler source): running
sum-of-squares accumulator (loop/recur → 385), grade cascade
(let-threaded if → 4/2/0), Horner polynomial straight-line build-up
(let-shadow chain → 73), multi-state bracket scanner threading
(rest,depth,ok) by tail recursion → true/false. 0 bugs, 0 friction,
0 spec_gap, 4 working — every task clean and correct on the first
try with only let/if/loop/recur; all parse|render|parse
byte-identical; zero mut/var/assign tokens produced (a doc-faithful
author did not reach for the removed construct).

The closest-to-friction case (multi-state machine restates the full
state tuple per tail-call) is correctly classified working, not a
spec_gap: that explicit-dataflow cost is the local-reasoning pillar
working as designed; mut's implicit cross-iteration persistence is
exactly the failure class the removal eliminates. mut-keyword
rejection is fail-closed with a diagnostic that enumerates the
surviving forms (no tombstone, no-nostalgia, as spec'd).

Removal thesis empirically CONFIRMED — mut was redundant with
let/if/loop/recur in 100% of the fresh tasks. The
remove-mut-var-assign milestone is fully ratified and CLOSED:
spec+plan+iter, audit clean (architect [high] form_a.md fixed in
.tidy, bench causally exonerated), fieldtest clean. Roadmap P0
flipped [~]→[x]; WhatsNew user-facing entry appended.
2026-05-18 11:28:34 +02:00

84 lines
3.0 KiB
Plaintext

; Axis: a small streaming-feel state machine threading MORE THAN
; ONE piece of state, updating only a SUBSET per branch.
;
; Scan a token stream (a recursive Int list; 1 = '(', 2 = ')',
; 0 = any other token) and decide if the brackets are balanced.
;
; Imperative instinct (exactly what `mut` would invite):
; depth = 0
; ok = true
; for t in stream:
; if t == 1: depth = depth + 1 ; only depth changes
; elif t == 2:
; if depth == 0: ok = false ; only ok changes
; else: depth = depth - 1 ; only depth changes
; ; t == 0 -> neither changes
; return ok && depth == 0
;
; Surviving-surface shape: a recursive scanner fn threading
; (rest, depth, ok) — `loop`/`recur` cannot walk an ADT (it rebinds
; positionally, there is no structural pattern in a recur), so the
; stream traversal is ordinary tail recursion; the per-branch
; "update a subset of the state" becomes "pass the unchanged values
; through unchanged". This is the task that most stresses the
; removal: an imperative author updates one variable and leaves the
; others implicitly alone; here every recur must restate all three.
;
; balanced "(()())" -> true ; stream 1 1 2 1 2 2
; balanced ")(" -> false ; stream 2 1
; Expected stdout (per line): true, false
(module remove-mut_4_bracket_scanner
(data TokStream
(doc "1='(' , 2=')' , 0=other.")
(ctor Nil)
(ctor Cons (con Int) (con TokStream)))
(fn scan
(doc "Thread (rest, depth, ok). Each arm updates a subset of state; the unchanged components must be restated in every tail call.")
(type
(fn-type
(params (own (con TokStream)) (con Int) (con Bool))
(ret (con Bool))))
(params rest depth ok)
(body
(match rest
(case (pat-ctor Nil)
(if ok (app == depth 0) false))
(case (pat-ctor Cons t more)
(match t
(case (pat-lit 1)
(tail-app scan more (app + depth 1) ok))
(case (pat-lit 2)
(if (app == depth 0)
(tail-app scan more depth false)
(tail-app scan more (app - depth 1) ok)))
(case _
(tail-app scan more depth ok)))))))
(fn balanced
(type (fn-type (params (own (con TokStream))) (ret (con Bool))))
(params s)
(body (app scan s 0 true)))
(fn main
(type (fn-type (params) (ret (con Unit)) (effects IO)))
(params)
(body
(seq
(app print
(app balanced
(term-ctor TokStream Cons 1
(term-ctor TokStream Cons 1
(term-ctor TokStream Cons 2
(term-ctor TokStream Cons 1
(term-ctor TokStream Cons 2
(term-ctor TokStream Cons 2
(term-ctor TokStream Nil)))))))))
(app print
(app balanced
(term-ctor TokStream Cons 2
(term-ctor TokStream Cons 1
(term-ctor TokStream Nil)))))))))