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 (SeeFile 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’.
 SeeEval.
 
    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 (SeeDefining 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 (SeeFile 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.  SeeByte 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.)