Tail optimization with labels
The lw manual states that: http://www.lispworks.com/documentation/lw50/LWUG/html/lwuser-98.htm 9.6.3 Tail call optimization In 64-bit LispWorks and on x86 platforms the compiler optimizes tail calls unless 1. The compiler optimize quality debug is 3, or 2. There is something with dynamic scope on the stack, such as a special binding, a catch or dynamic-extent allocation (so it is not really a tail call) In my code, I have something like this (a lot of things are removed to isolate the things that trigger/disable tail optimization) (defun amber2 (expr success fail) (declare (optimize (debug 0))) (labels ((done (val) (if val (funcall success) (funcall fail)))) (cond ((null expr) (done expr)) ((atom expr) (done expr)) (t (amber2 (cdr expr) success fail))))) ;; (disassemble 'amber2) ;; => ;; 133: FF1544289021 call [21902844] ; AMBER2 It took me a while to find out that if I replace labels with flet then tail calls are optimized. (defun amber1 (expr success fail) (declare (optimize (debug 0))) (flet ((done (val) (if val (funcall success) (funcall fail)))) (cond ((null expr) (done expr)) ((atom expr) (done expr)) (t (amber1 (cdr expr) success fail))))) ;; (disassemble 'amber1) ;; 77: EBC7 jmp L1 For the above demo code it's perfectly fine to replace labels with flet. But if I really need to call "done" within "done" recursively then I cannot substitute labels. Question: Does labels create any dynamic bindings? If not, is this a bug or something that cannot be work around? Thanks.