LexicalBinding

For a discussion, see DynamicBindingVsLexicalBinding.

Emacs 24 has optional lexical binding, which can be enabled on a per-buffer basis.
To use it, set the buffer-local variable ‘lexical-binding’ to a non-nil value.

For closures on previous versions of Emacs, see FakeClosures.

(setq lexical-binding t)
(setq test (let ((foo "bar"))
	     (lambda () 
	       foo)))
=> (closure ((foo . "bar") t) nil foo)
(funcall test)
=> "bar"                                ; without lexical binding, it would have failed due to an unbound variable
(let ((foo "something-else"))
  (funcall test))
=> "bar"                                ; without lexical binding, it would have returned "something-else"

Problem with defun in lexically bound contexts. (For Emacs 24 prior to 24.3)

Prior to Emacs 24.3, the defun special form didn’t work properly in lexically bound contexts (i.e. when the buffer-local variable lexical-binding in not nil). For example:

(let ((counter 0))
  (defun counting ()
    (setq counter (1+ counter))))

would not work as expected because the symbol counter in the function’s body would be dynamically bound instead of binding to the variable defined in the let.

The byte compiler did give a warning if you used defun in this way.

This issue was resolved in Emacs 24.3, where the defun special form was replaced by a macro that doesn’t have this issue.
In versions prior to 24.3, the following macro can be used as a work-around:

(defmacro defun** (name arglist &rest body)
  "Define NAME as a function in a lexically bound context.

Like normal `defun', except that it works correctly in lexically
bound contexts in versions of Emacs 24 prior to 24.3.

\(fn NAME ARGLIST [DOCSTRING] BODY...)"
  (when (fboundp `,name)
    (message "Redefining function/macro: %s" `,name))
  `(eval-and-compile
     (fset (quote ,name) (lambda (,@arglist) ,@body))))

If you define counting as follows:

(let ((counter 0))
  (defun** counting ()
    (setq counter (1+ counter))))

it will work as expected and update the lexically bound variable counter every time it is invoked, while returning the new value.

NOTE: The macro always makes a globally visible function even if you try to use it in a lexical closure. For instance, if you do the following:

(let ((something 10))
  (defun** something ()
    .........
    .........))

you get a lexical closure with a variable binding for the symbol something, but the function being defined will still be stored in the function cell of the symbol something, which is global. In short, remember that elisp is a lisp-2, and let binds variables only.

If you want lexically bound functions, you can use cl-flet or cl-lables from the cl package.
Alternatively, you can assign lambdas to variables and then use them with funcall, for example:

(let ((foo (lambda ()
	     "I am foo.")))
  (defun bar ()
    (funcall foo)))
(bar)
=> "I am foo."

However, like with cl-flet, this doesn’t allow the functions to recurse.

For recursion you need more machinery. The make-rec macro (below) takes a name, and a function (which may use that name) and returns an anonymous recursive function. (Note: the use of funcall is still required)

(defmacro make-rec (name fun)
  `((lambda (x) (funcall x x))
    (lambda (y)
      (funcall (lambda (,name) ,fun) (lambda (&rest args) (apply (funcall y y) args))))))
(let ((fac (make-rec f
                     (lambda (n) (if (= n 0) 1 (* n (funcall f (1- n))))))))
 (defun bar (n)
   (funcall fac n)))
(bar 5)
=> 120

Note: I have named the macro defun** so that it doesn’t clash with the macro defun* in the cl package, however it doesn’t depend on that package. — Bernard Hurley

Using lexical binding in elisp libraries

To enable lexical binding in your elisp library, put a line like this at the top of the file:

;; -*- lexical-binding: t -*-

This will enable lexical-binding for the code in the file, but note that global variables declared with defvar, defcustom or defconst will be dynamically bound due to the global binding being marked as “special” by those forms.
Note: as of Emacs 24.4, any closures created before marking the variable as “special” are unaffected by this effect. It’s not clear whether this is intentional. (I could reproduce this in SBCL, but not CLISP. Maybe it’s supposed to have undefined behavior.)

Note: as of Emacs 24.4, the undocumented internal-make-var-non-special function does not work as expected, and the only known way to revert a special variable status is restarting Emacs. makunbound doesn’t help, either.

Real world issues

One problem with using lexical binding is debugging. ‘eval’ in especially in edebbug is unusable because the ‘print’ed version of the closures would take half a screen. Is there any way to tell emacs to reduce the printout a closure (e.g. #<closure>)? --LinhDang


CategoryCode