Next: , Previous: , Up: Local Call   [Contents][Index]


5.6.2 Let Calls

Because local call avoids unnecessary call overheads, the compiler internally uses local call to implement some macros and special forms that are not normally thought of as involving a function call. For example, this let:

(let ((a (foo))
      (b (bar)))
  ...)

is internally represented as though it was macroexpanded into:

(funcall #'(lambda (a b)
             ...)
         (foo)
         (bar))

This implementation is acceptable because the simple cases of local call (equivalent to a let) result in good code. This doesn’t make let any more efficient, but does make local calls that are semantically the same as let much more efficient than full calls. For example, these definitions are all the same as far as the compiler is concerned:

(defun foo ()
  ...some other stuff...
  (let ((a something))
    ...some stuff...))

(defun foo ()
  (flet ((localfun (a)
           ...some stuff...))
    ...some other stuff...
    (localfun something)))

(defun foo ()
  (let ((funvar #'(lambda (a)
                    ...some stuff...)))
    ...some other stuff...
    (funcall funvar something)))

Although local call is most efficient when the function is called only once, a call doesn’t have to be equivalent to a let to be more efficient than full call. All local calls avoid the overhead of argument count checking and keyword argument parsing, and there are a number of other advantages that apply in many common situations. See let-optimization for a discussion of the optimizations done on let calls.


Next: Closures, Previous: Self-Recursive Calls, Up: Local Call   [Contents][Index]