Named let creates a loop continuation but set! inside the loop body does not mutate bindings in the enclosing let scope. Affects both the WASM kernel and native OCaml CEK evaluator. 6 failing Node tests cover: - set! counter (simplest case) - set! counter with named let params - set! list accumulator via append - append! + set! counter combo - set! string concatenation - nested named let set! 3 baselines pass: plain let set!, functional named let, plain append! Also adds spec/tests/test-named-let-set.sx (7 assertions, first fails and aborts — confirms bug exists in spec test suite too). This is the root cause of empty source code blocks on all example pages: tokenize-sx uses set! in named let → empty tokens → highlight returns "(<> )" → empty <code> blocks. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
53 lines
1.1 KiB
Plaintext
53 lines
1.1 KiB
Plaintext
(assert=
|
|
(let ((x 0)) (let loop () (when (< x 5) (set! x (+ x 1)) (loop))) x)
|
|
5
|
|
"set! counter in named let loop")
|
|
|
|
(assert=
|
|
(let
|
|
((acc (list)))
|
|
(let
|
|
loop
|
|
((i 0))
|
|
(when (< i 3) (set! acc (append acc (list i))) (loop (+ i 1))))
|
|
acc)
|
|
(list 0 1 2)
|
|
"set! list accumulator in named let with param")
|
|
|
|
(assert=
|
|
(let
|
|
((acc (list)) (i 0))
|
|
(let loop () (when (< i 3) (append! acc i) (set! i (+ i 1)) (loop)))
|
|
acc)
|
|
(list 0 1 2)
|
|
"append! + set! counter in named let")
|
|
|
|
(assert=
|
|
(let
|
|
((sum 0))
|
|
(let
|
|
loop
|
|
((i 1))
|
|
(when (<= i 10) (set! sum (+ sum i)) (loop (+ i 1))))
|
|
sum)
|
|
55
|
|
"set! sum in named let loop (1..10)")
|
|
|
|
(assert=
|
|
(let
|
|
((result ""))
|
|
(let
|
|
loop
|
|
((i 0))
|
|
(when (< i 3) (set! result (str result (str i))) (loop (+ i 1))))
|
|
result)
|
|
"012"
|
|
"set! string accumulator in named let")
|
|
|
|
(assert= (let ((x 0)) (set! x 42) x) 42 "set! in plain let (baseline)")
|
|
|
|
(assert=
|
|
(let loop ((i 0) (acc 0)) (if (< i 5) (loop (+ i 1) (+ acc i)) acc))
|
|
10
|
|
"named let without set! (baseline)")
|