Résumé : Note about using lexical-binding in libraries
< This will enable lexical-binding for the code in the file.
> This will enable lexical-binding for the code in the file, but global variables declared with `defvar' will still be
> dynamically bound.
For a discussion, see DynamicBindingVsLexicalBinding.
Emacs 24 has lexical binding, if you want it. To use it, set
‘lexical-binding’ and evaluate code in the same buffer.
You can have closures in Emacs – no need for FakeClosures!
(setq lexical-binding t) (setq test (let ((foo "bar")) (lambda () (message foo)))) => (closure ((foo . "bar") t) nil (message foo)) (funcall test) => "bar" (let ((foo "something-else")) (funcall test)) => "bar" ; would have printed "something-else" with dynamic binding
defun special form doesn’t work properly in lexically bound contexts (i.e. when
lexical-bindint has value
t) as of Emacs 24.2.1. For example:
(let ((counter 0)) (defun counting () (setq counter (1+ counter))))
will not work as expected because the symbol
counter in the
defun will be bound to the global variable of that name, if there is one and not the lexical variable define in the
let. When the function
counting is called, if the variable doesn’t, exist then it will obviously fail. Hoever if there is such a global variable it be updated, which is probably not what was intended and could be a hard to trace bug since the function might appear to be working properly.
The byte compiler does give a warning if you use
defun in this way and presumably the issue will be addressed in some future version of Emacs, but until then the following macro can be used:
(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. \(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
counter as follows:
(let ((counter 0)) (defun** counting () (setq counter (1+ counter))))
it will work as expected and update the lexically bound variable
count every time it is invoked, while returning the new value.
NOTE: The macro always makes a globally visible function even if you try binding the function to a lexical variable. For instance, if you do the following:
(let ((something 10)) (defun** something () ......... .........))
you get two symbols with the same name:
something. One is lexically bound to number 10 and one is bound to a non-lexically bound function. If you want lexically bound functions you can use the
lables macro from the cl package.
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
As of 2013-01-15, `defun` in the Emacs trunk appears to work correctly in lexically bound contexts so this hack is no longer needed. — Bernard Hurley
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 global variables declared with
‘defvar’ will still be dynamically bound.