Tail Call Optimization
I know that LW can optimize tail calls in many cases. I have seen it many times. But being able to predict when it can occur is next to impossible.I have instances where the tail call is through a captured closure stored in a local binding, or in one of the bindings of the closure of the current function. And in those cases it seems that LW refuses to perform a tail call through that pointer, no matter how I declare the optimization to the compiler. There is only a single value that I’m passing to the captured closure, so it isn’t a question of too many args, or keyword args, etc., interfering.
So it seems that compiler declarations are a weak method of invoking what you want, when you absolutely know you should be getting tail calls. Why not implement a Lisp primitive that directly performs a tail call, i.e., JMP with args?
(Stupid) Example that blows the stack:
(let ((sav-k #'values)
(sav-n 500))
(block myblock
(tagbody top
(let ((k sav-k)
(n sav-n))
(return-from myblock
(if (< n 2)
(funcall k 1)
(let ((k (let ((k k) ;; form our own captures just to be certain...
(n n)) ;; should not be necessary here
(lambda (t1)
(funcall k (* t1 n))))))
(setf sav-k k
sav-n (1- n))
(go top))
))))))
- David McClain
Refined Audiometrics Laboratory
Tucson, AZ, USA