Übersicht Letzte Änderungen Neuigkeiten Suchen ElispSektion KurzAnleitung Impressum

LexicalBinding

Letzte Änderung

Zusammenfassung: Note about using lexical-binding in libraries

Geändert:

< This will enable lexical-binding for the code in the file.

stattdessen:

> 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

Using defun in lexically bound contexts.

the 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

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 global variables declared with ‘defvar’ will still be dynamically bound.


CategoryCode