Lexical Bindings
----------------
The "CL" package defines the following macro which more closely follows
the Common Lisp `let' form:
- Special Form: lexical-let (bindings...) forms...
This form is exactly like `let' except 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 `lexical-let' (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 `a' actually makes a
temporary change to the global variable `a', so `foo' is able to
see the binding of `a' to 2. But `lexical-let' 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. For example:
(defun make-adder (n)
(lexical-let ((n n))
(function (lambda (m) (+ n m)))))
(setq add17 (make-adder 17))
(funcall add17 4)
=> 21
The call `(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 global `n', which
would have been bound to 17 only during the call to `make-adder'
itself.
(defun make-counter ()
(lexical-let ((n 0))
(function* (lambda (&optional (m 1)) (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
local variable `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 `n'. Of course, if a `lexical-let'
does not actually create any closures, then the lexical variables
are free as soon as the `lexical-let' returns.
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 `lexical-let'
closures:
(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 `defun' or `flet' inside a `lexical-let' 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.
The `lexical-let' form is an extension to Common Lisp. In true
Common Lisp, all bindings are lexical unless declared otherwise.
- Special Form: lexical-let* (bindings...) forms...
This form is just like `lexical-let', except that the bindings are
made sequentially in the manner of `let*'.