elisp: Using Lexical Binding
11.9.4 Using Lexical Binding
----------------------------
When loading an Emacs Lisp file or evaluating a Lisp buffer, lexical
binding is enabled if the buffer-local variable ‘lexical-binding’ is
non-‘nil’:
-- Variable: lexical-binding
If this buffer-local variable is non-‘nil’, Emacs Lisp files and
buffers are evaluated using lexical binding instead of dynamic
binding. (However, special variables are still dynamically bound;
see below.) If ‘nil’, dynamic binding is used for all local
variables. This variable is typically set for a whole Emacs Lisp
file, as a file local variable (File Local Variables).
Note that unlike other such variables, this one must be set in the
first line of a file.
When evaluating Emacs Lisp code directly using an ‘eval’ call, lexical
binding is enabled if the LEXICAL argument to ‘eval’ is non-‘nil’.
Eval.
Even when lexical binding is enabled, certain variables will continue
to be dynamically bound. These are called “special variables”. Every
variable that has been defined with ‘defvar’, ‘defcustom’ or ‘defconst’
is a special variable (Defining Variables). All other variables
are subject to lexical binding.
-- Function: special-variable-p symbol
This function returns non-‘nil’ if SYMBOL is a special variable
(i.e., it has a ‘defvar’, ‘defcustom’, or ‘defconst’ variable
definition). Otherwise, the return value is ‘nil’.
The use of a special variable as a formal argument in a function is
discouraged. Doing so gives rise to unspecified behavior when lexical
binding mode is enabled (it may use lexical binding sometimes, and
dynamic binding other times).
Converting an Emacs Lisp program to lexical binding is easy. First,
add a file-local variable setting of ‘lexical-binding’ to ‘t’ in the
header line of the Emacs Lisp source file (File Local
Variables). Second, check that every variable in the program which
needs to be dynamically bound has a variable definition, so that it is
not inadvertently bound lexically.
A simple way to find out which variables need a variable definition
is to byte-compile the source file. Byte Compilation. If a
non-special variable is used outside of a ‘let’ form, the byte-compiler
will warn about reference or assignment to a free variable. If a
non-special variable is bound but not used within a ‘let’ form, the
byte-compiler will warn about an unused lexical variable. The
byte-compiler will also issue a warning if you use a special variable as
a function argument.
(To silence byte-compiler warnings about unused variables, just use a
variable name that start with an underscore. The byte-compiler
interprets this as an indication that this is a variable known not to be
used.)