Some caveats about this method:
- The "call" in the name of
_tco_
is a lie. It's tail recursion, not tail call optimization. I'll update the name if I include this in sibilant. - It drops some boilerplate (the
_tco_
function) at the top, which is something I don't feel too good about. - It only works from a tail position — if you don't return
(recur ...)
, it does nothing.
It can be enabled either globally:
(enable-tco)
(defun infinite-loop () (recur)) ;=> infinite loop, no stack
(disable-tco)
(defun no-tco () (recur)) ;=> throws, doesn't know what recur means
Or just for a block:
(with-tco
(defun infinite-loop () (recur)))
(defun normal-function-here () (infinite-loop)) ;=> functions defined within tco still work