; 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)) (own (con Int)) (own (con Bool))) (ret (own (con Bool))))) (params rest depth ok) (body (match rest (case (pat-ctor Nil) (if ok (app eq 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 eq 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 (own (con Bool))))) (params s) (body (app scan s 0 true))) (fn main (type (fn-type (params) (ret (own (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)))))))))