28 lines
905 B
Common Lisp
28 lines
905 B
Common Lisp
; test_tco.lisp — proper tail calls. Each form below would have blown
|
|
; the C stack pre-TCO (segfault around ~25k recursive calls). The
|
|
; counts here are deliberately past that line and across all three
|
|
; tail positions: if-tail, begin-tail, let-tail.
|
|
|
|
; if-tail: classic accumulator countdown.
|
|
(define spin
|
|
(lambda (n a)
|
|
(if (= n 0) a (spin (- n 1) (+ a 1)))))
|
|
(spin 30000 0)
|
|
|
|
; begin-tail: last form of a begin block is the recursive call.
|
|
(define bspin
|
|
(lambda (n a)
|
|
(if (= n 0) a (begin a (bspin (- n 1) (+ a 1))))))
|
|
(bspin 30000 0)
|
|
|
|
; let-tail: last form of a let body is the recursive call.
|
|
(define lspin
|
|
(lambda (n a)
|
|
(if (= n 0) a (let ((m (- n 1))) (lspin m (+ a 1))))))
|
|
(lspin 30000 0)
|
|
|
|
; gcd: tail call from the else branch of an if (already tested by
|
|
; lisp_test, kept here as a nice short demo).
|
|
(define gcd (lambda (a b) (if (= b 0) a (gcd b (mod a b)))))
|
|
(gcd 1071 462)
|