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.