Next: Closures, Previous: Self-Recursive Calls, Up: Local Call [Contents][Index]
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]