The following macros are extensions to Common Lisp, where all bindings are lexical unless declared otherwise. These features are likewise obsolete since the introduction of true lexical binding in Emacs 24.1.
This form is exactly like
letexcept that the bindings it establishes are purely lexical.
Lexical bindings are similar to local variables in a language like C:
Only the code physically within the body of the
(after macro expansion) may refer to the bound variables.
(setq a 5) (defun foo (b) (+ a b)) (let ((a 2)) (foo a)) ⇒ 4 (lexical-let ((a 2)) (foo a)) ⇒ 7
In this example, a regular
let binding of
makes a temporary change to the global variable
is able to see the binding of
a to 2. But
actually creates a distinct local variable
a for use within its
body, without any effect on the global variable of the same name.
The most important use of lexical bindings is to create closures. A closure is a function object that refers to an outside lexical variable (see Closures). For example:
(defun make-adder (n) (lexical-let ((n n)) (function (lambda (m) (+ n m))))) (setq add17 (make-adder 17)) (funcall add17 4) ⇒ 21
(make-adder 17) returns a function object which adds
17 to its argument. If
let had been used instead of
lexical-let, the function object would have referred to the
n, which would have been bound to 17 only during the
(defun make-counter () (lexical-let ((n 0)) (cl-function (lambda (&optional (m 1)) (cl-incf n m))))) (setq count-1 (make-counter)) (funcall count-1 3) ⇒ 3 (funcall count-1 14) ⇒ 17 (setq count-2 (make-counter)) (funcall count-2 5) ⇒ 5 (funcall count-1 2) ⇒ 19 (funcall count-2) ⇒ 6
Here we see that each call to
make-counter creates a distinct
n, which serves as a private counter for the
function object that is returned.
Closed-over lexical variables persist until the last reference to
them goes away, just like all other Lisp objects. For example,
count-2 refers to a function object which refers to an
instance of the variable
n; this is the only reference
to that variable, so after
(setq count-2 nil) the garbage
collector would be able to delete this instance of
Of course, if a
lexical-let does not actually create any
closures, then the lexical variables are free as soon as the
Many closures are used only during the extent of the bindings they
refer to; these are known as “downward funargs” in Lisp parlance.
When a closure is used in this way, regular Emacs Lisp dynamic
bindings suffice and will be more efficient than
(defun add-to-list (x list) (mapcar (lambda (y) (+ x y))) list) (add-to-list 7 '(1 2 5)) ⇒ (8 9 12)
Since this lambda is only used while
x is still bound,
it is not necessary to make a true closure out of it.
You can use
flet inside a
to create a named closure. If several closures are created in the
body of a single
lexical-let, they all close over the same
instance of the lexical variable.