From: Jim Meehan
Subject: Re: FAQ and compiled-call optimization
Date: 
Message-ID: <1991Aug25.230231.8723@src.dec.com>
In article <····················@poincare.math.ufl.edu> Jonathan King
asks:

    Is there an FAQ for Common Lisp?

No, but Barry Margolin (······@think.com) answers them anyway. :-)

    Suppose I have a function of the form
    
    (defun recursive (var unchanging)
      (unless (test)
        (recursive (change var) unchanging) )
      (furthercomputation)  ; This does not affect UNCHANGING.
      )	
    
    Since the variable UNCHANGING never changes, it seems a shame to keep
    passing it, in compiled code.  
    
It may not actually cost all that much, e.g, another slot on the stack.
But it can be a nuisance, especially when there are several unchanging
variables.  I would do this:

(defun recursive (var unchanging)
  (labels ((inner (var)
             (unless (test)
               (inner (change var)))
             (furthercomputation)))
    (inner var)))

That would limit the recursion to the changing var.

    Does proclaiming RECURSIVE to be `inline' solve this problem?

No. In fact, that would be peculiar.  You should imagine that declaring
a function 'inline' causes function-calls to be macroexpanded, so that
would lead to infinite code-expansion for recursive functions.  
(Of course, compilers don't really do that, although I know one that did.)
    
    Is the following solution (1) Correct?  (2) Acceptable programming
    practice?
    
    (defun recursive (var unchanging)
      (declare (special unchanging))
      (helper var) )
    
    (defun helper (var)
      (unless (test)
        (helper (change var) unchanging) )
      (furthercomputation)  ; This does not affect UNCHANGING.
      )	
    
1. You should add (declare (special unchanging)) to the helper
function, but assuming that test, change, furthercomputation, and the
functions that THEY call don't refer to a special variable named
unchanging, it is correct.  Standard practice is to spell special
variables with stars: *unchanging*.

2. I wouldn't do it for a simple case like this, but your mileage may
vary.  For example, if your implementation of Common Lisp has a very
efficient mechanism for binding and accessing special variables, AND
it does a terrible job with local functions like 'inner' that access
closed-over variables AND 'inner' is going to be called many, many
times, then it's worth considering.  I.e., write it both ways and
measure the performance.