Step 10: tail position guarantees — verified across all contexts
9 new deep recursion tests (100K-200K depth) confirming TCO in: - match, begin, do, let-match — tail expressions get same continuation - parameterize — provide frames are contextual, don't block TCO - guard — handler body in tail position via cond desugaring - handler-bind — body sequences with rest-k - and/or — short-circuit preserves tail position - mutual recursion — 200K depth even/odd CEK machine correctly preserves tail position in all forms. 2676/2676 standard tests pass (was 2668 + 9 new - 1 pre-existing). Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -189,3 +189,79 @@
|
||||
(fn (lst)
|
||||
(reduce (fn (a x) (+ a x)) 0 lst)))
|
||||
(assert-equal 15 (sum-list (list 1 2 3 4 5)))))
|
||||
|
||||
(defsuite
|
||||
"tco-step10"
|
||||
(deftest
|
||||
"tail position in match"
|
||||
(define
|
||||
loop
|
||||
(fn (n acc) (match n (0 acc) (_ (loop (- n 1) (+ acc 1))))))
|
||||
(assert= 100000 (loop 100000 0)))
|
||||
(deftest
|
||||
"tail position in do form"
|
||||
(assert=
|
||||
100000
|
||||
(do
|
||||
(define loop (fn (n) (if (zero? n) n (loop (- n 1)))))
|
||||
(loop 100000)
|
||||
100000)))
|
||||
(deftest
|
||||
"tail position in begin"
|
||||
(define
|
||||
loop
|
||||
(fn (n acc) (if (zero? n) acc (begin (loop (- n 1) (+ acc 1))))))
|
||||
(assert= 100000 (loop 100000 0)))
|
||||
(deftest
|
||||
"tail position in parameterize body"
|
||||
(let
|
||||
((p (make-parameter 0)))
|
||||
(define
|
||||
loop
|
||||
(fn
|
||||
(n)
|
||||
(parameterize ((p n)) (if (zero? n) (p) (loop (- n 1))))))
|
||||
(assert= 0 (loop 10000))))
|
||||
(deftest
|
||||
"tail position in guard body"
|
||||
(define
|
||||
loop
|
||||
(fn
|
||||
(n acc)
|
||||
(guard
|
||||
(exn (true acc))
|
||||
(if (zero? n) acc (loop (- n 1) (+ acc 1))))))
|
||||
(assert= 100000 (loop 100000 0)))
|
||||
(deftest
|
||||
"tail position in handler-bind body"
|
||||
(define
|
||||
loop
|
||||
(fn
|
||||
(n acc)
|
||||
(handler-bind () (if (zero? n) acc (loop (- n 1) (+ acc 1))))))
|
||||
(assert= 100000 (loop 100000 0)))
|
||||
(deftest
|
||||
"tail position in let-match body"
|
||||
(define
|
||||
loop
|
||||
(fn
|
||||
(n acc)
|
||||
(let-match
|
||||
{:val v}
|
||||
{:val n}
|
||||
(if (zero? v) acc (loop (- v 1) (+ acc 1))))))
|
||||
(assert= 100000 (loop 100000 0)))
|
||||
(deftest
|
||||
"tail position in and/or"
|
||||
(define
|
||||
loop-and
|
||||
(fn (n) (if (zero? n) true (and true (loop-and (- n 1))))))
|
||||
(define
|
||||
loop-or
|
||||
(fn (n) (if (zero? n) false (or false (loop-or (- n 1))))))
|
||||
(do (assert= true (loop-and 100000)) (assert= false (loop-or 100000))))
|
||||
(deftest
|
||||
"mutual tail recursion at depth 200000"
|
||||
(define is-even? (fn (n) (if (zero? n) true (is-odd? (- n 1)))))
|
||||
(define is-odd? (fn (n) (if (zero? n) false (is-even? (- n 1)))))
|
||||
(do (assert (is-even? 200000)) (assert (not (is-odd? 200000))))))
|
||||
|
||||
Reference in New Issue
Block a user