Files
ww/examples/lisp/test_tco.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)