Optionally, you can create lexical bindings in Emacs Lisp. A lexically bound variable has lexical scope, meaning that any reference to the variable must be located textually within the binding construct.
Here is an example (see Using Lexical Binding, for how to actually enable lexical binding):
(let ((x 1)) ;
xis lexically bound. (+ x 3)) ⇒ 4 (defun getx () x) ;
xis used ``free'' in this function. (let ((x 1)) ;
xis lexically bound. (getx)) error--> Symbol's value as variable is void: x
Here, the variable
x has no global value. When it is lexically
bound within a
let form, it can be used in the textual confines
let form. But it can not be used from within a
getx function called from the
let form, since the
function definition of
getx occurs outside the
Here is how lexical binding works. Each binding construct defines a lexical environment, specifying the symbols that are bound within the construct and their local values. When the Lisp evaluator wants the current value of a variable, it looks first in the lexical environment; if the variable is not specified in there, it looks in the symbol's value cell, where the dynamic value is stored.
Lexical bindings have indefinite extent. Even after a binding construct has finished executing, its lexical environment can be “kept around” in Lisp objects called closures. A closure is created when you define a named or anonymous function with lexical binding enabled. See Closures, for details.
When a closure is called as a function, any lexical variable references within its definition use the retained lexical environment. Here is an example:
(defvar my-ticker nil) ; We will use this dynamically bound ; variable to store a closure. (let ((x 0)) ;
xis lexically bound. (setq my-ticker (lambda () (setq x (1+ x))))) ⇒ (closure ((x . 0) t) () (1+ x)) (funcall my-ticker) ⇒ 1 (funcall my-ticker) ⇒ 2 (funcall my-ticker) ⇒ 3 x ; Note that
xhas no global value. error--> Symbol's value as variable is void: x
let binding defines a lexical environment in which the
x is locally bound to 0. Within this binding
construct, we define a lambda expression which increments
one and returns the incremented value. This lambda expression is
automatically turned into a closure, in which the lexical environment
lives on even after the
let binding construct has exited. Each
time we evaluate the closure, it increments
x, using the
x in that lexical environment.
Note that functions like
set only retrieve or modify a variable's dynamic binding
(i.e., the contents of its symbol's value cell). Also, the code in
the body of a
defmacro cannot refer to
surrounding lexical variables.
Currently, lexical binding is not much used within the Emacs sources. However, we expect its importance to increase in the future. Lexical binding opens up a lot more opportunities for optimization, so Emacs Lisp code that makes use of lexical binding is likely to run faster in future Emacs versions. Such code is also much more friendly to concurrency, which we want to add to Emacs in the near future.