Lisp HUG Maillist Archive

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.



finish-output required?

I have been writing alternately to two output streams. If I don't include 
finish-output after writing to each of them, nothing is written to one of the 
files. Is this the expected behavior?  This is with Windows XP.  Thank you.

Mitch 


Updated at: 2020-12-10 08:47 UTC