DynamicBindingVsLexicalBinding

Lexical and dynamic binding refer to how variables are looked up by their names. Lexical binding is sometimes called static binding. The naming contrast between “static binding” and “dynamic binding” is more obvious, however the difference is somewhat more subtle than simply whether a binding changes over time.

Binding

A binding is a correspondence between a name and its value.

In Lisp you can create a binding using ‘let’:

   (let ((a 1)) (print a))
     ==> 1

This creates a fresh location, puts the value 1 there, and binds the name “a” to it.

Each use of ‘let’ creates a fresh location, even if you use the same name:

   (let ((a 1))
     (let ((a 2))
        (let ((a 3))
          (print a))
        (print a))
     (print a))
     ==> 3
         2
         1

A binding made by ‘let’ lasts until the end of the ‘let’ form.

Function calls create bindings for their formal arguments when they are called:

    (defun foo (a)
      (let ((a 2)) (print a))
      (print a))
    (foo 1)
    ==> 2
        1

A binding made by a function call lasts until the call returns.

A ‘let’ expression is indeed just “syntactic sugar”, a convenience, for the corresponding ‘lambda’ form:

    (let ((a 1)
          (b 3))
      (+ a b))

is equivalent to

    ((lambda (a b) (+ a b)) 1 3)

Note that there are plenty of other ways to make bindings: ‘defconst’, ‘defun’, ‘defvar’, ‘flet’, ‘labels’, ‘prog’, etc.

Dynamic and Lexical Binding

Two regimes for handling variable binding emerged:

dynamic
All variable names and their values live in one global table.
lexical
Each binding scope (function, let syntax, …) creates a new table of variable names and values, organised in a hierarchy called “the environment”.

For the simple examples given above both lexical and dynamic binding return the same results. But consider this piece of code:

    (let ((a 1))                            ; binding (1)
      (let ((f (lambda () (print a))))
        (let ((a 2))                        ; binding (2)
          (funcall f))))
    ==> ?

A name that is lexically bound is looked up only in bindings in the lexical environment of the name – that is, in bindings that enclose the name in the source code. So if “a” is lexically bound, the code above prints “1”, because only binding (1) is in the lexical environment. When there are multiple bindings in the lexical environment, the innermost one is used.

A name that is dynamically bound is looked up only in bindings in the dynamic environment of the name – that is, in all bindings which have been created since the program began and which have not yet been destroyed. When there are multiple bindings in the dynamic environment, the most recently created one is used. So if “a” is dynamically bound, the code above prints “2” because both binding (1) and binding (2) have been created by the time “a” is evaluated, but binding (2) was created more recently.

(In a multi-threaded Lisp we would have to be a bit more careful about dynamic binding to make sure that one thread doesn’t see bindings created on another thread. But EmacsLisp is single-threaded so that’s not a worry.)

Another example which shows the difference

This is a lambda function which adds 3 to a number: (lambda (arg) (+ 3 arg)). You may apply it so: ((lambda (arg) (+ 3 arg)) 5) and it gives 8.

Now you want to store the 3 somewhere else (let’s say in variable to_add) but still get a function which adds 3 (not other possible values of to_add, but the current one). You could try: (let ((to_add 3)) (lambda (arg) (+ to_add arg)) ). But it doesn’t work because you get: (lambda (arg) (+ to_add arg)) instead of (lambda (arg) (+ 3 arg)). The first one will not work if the value of the variable to_add had changed by the time the lambda is applied. The cause of this result is that the binding is dynamic, not lexical. Notice the difference.

Now for how to do what you wanted. This wouldn’t work either: (let ((to_add 3)) `(lambda (arg) (+ ,to_add arg)) ) because it is not a closure, it is a substitution (see: BackquoteSyntax). A solution would be: (lexical-let ((to_add 3)) (lambda (arg) (+ to_add arg))), which can be applied with funcall: (funcall (lexical-let ((to_add 3)) (lambda (arg) (+ to_add arg))) 5) is 8. More on the theory is below, and other solutions in FakeClosures.

Advantages of dynamic binding

Dynamic bindings are great for modifying the behaviour of subsystems. Suppose you are using a function ‘foo’ that generates output using ‘print’. But sometimes you would like to capture the output in a buffer of your choosing. With dynamic binding, it’s easy:

   (let ((b (get-buffer-create " *string-output*")))
     (let ((standard-output b))
       (print "foo"))
     (set-buffer b)
     ;; do stuff with the output of foo
     (insert "bar")
     (buffer-string))

(And if you used this kind of thing a lot, you’d encapsulate it in a macro – but luckily it’s already been done as ‘with-output-to-temp-buffer’.)

This works because ‘foo’ uses the dynamic binding of the name ‘standard-output’, so you can substitute your own binding for that name to modify the behaviour of ‘foo’ – and of all the functions that ‘foo’ calls.

In a language without dynamic binding, you’d probably add an optional argument to ‘foo’ to specify a buffer and then ‘foo’ would pass that to any calls to ‘print’. But if ‘foo’ calls other functions which themselves call ‘print’ you’ll have to alter those functions as well. And if ‘print’ had another option, say ‘print-level’, you’d have to add that as an optional argument as well… Alternatively, you could remember the old value of ‘standard-output’, substitute your new value, call ‘foo’ and then restore the old value. And remember to handle non-local exits using ‘throw’. When you’re through with this, you’ll see that you’ve implemented dynamic binding!

RichardStallman explains the advantages of dynamic binding in the context of EmacsLisp: http://www.gnu.org/software/emacs/emacs-paper.html#SEC17. See also the article Dynamic vs. Static Typing — A Pattern-Based Analysis by Pascal Costanza, http://www.p-cos.net/documents/dynatype.pdf.

Advantages of lexical binding

From: MilesBader
Subject: Re: Emacs 22
Newsgroups: comp.emacs
Date: Sun, 19 Aug 2001 01:47:53 GMT

Because it's (1) much easier for the user [that is, programmer], because
it eliminates the problem of which variables lambda-expressions use
(when they attempt to use variables from their surrounding context), and
(2) much easier for the compiler to optimize, because it doesn't need to
worry about variables escaping their lexical context, and so doesn't
need to allow for the possibility (this is a big problem with the
current compiler).

Languages

Most languages only have lexical bindings for names.

Why Emacs has Dynamic Binding

RichardStallman wrote a paper describing the design of the original Emacs and the lessons to be learned from it. It also contains a great section on dynamic binding.

See node Dynamic Binding in the EmacsLispReference.

Moving Towards Lexical Binding

To use lexical binding, an Emacs-lisp source file must set a file-local variable ‘lexical-binding’ to ‘t’ in the file header, e.g., by using a first line such as this:

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

Even in a source file that uses lexical binding, global variables declared with ‘defvar’ are always dynamically scoped.

Much code written for normal EmacsLisp should work unchanged when using lexical binding, because good Lisp programming practice tends to discourage the sort of code that would expose the difference (e.g., ‘let’-binding an undeclared variable and intending that the value be seen by a called function).

Emacs Future lexical Binding

StefanMonnier has said more about how lexical binding in Emacs could behave:

More Radical Approaches

DownWithEmacsLisp

Simulating Lexical Binding in older Emacs Versions

See this page: FakeClosures. Other tips are given below.

If you `(require ‘cl)’ then you can make lexical bindings with the ‘lexical-let’ macro:

    (lexical-let ((foo 1))
      (defun foo-test () foo)
      (defun foo-inc ()
        (incf foo)))
      => foo-inc
    (foo-test)
      => 1
    (foo-test)
      => 1
    (foo-inc)
      => 2
    (foo-test)
      => 2

[Use `(eval-when-compile (require ‘cl))’ if you intend to distribute such code, to avoid runtime dependence on ‘cl’ in the compiled code.]

How can it be? ‘foo-test’ actually references a shared, hidden value slot. That’s because library cl uses macro hackery to simulate lexical binding. Examine it yourself:

    (with-output-to-temp-buffer (pp (symbol-function 'foo-test)))
      => (lambda
	   (&rest --cl-rest--)
	   (apply
	    '(lambda
	       (G58033)
	       (symbol-value G58033))
	    '--foo-- --cl-rest--))
         nil

Note that this isn’t the same thing as actually having lexical variables in the language.

It’s also possible to use a macro to facilitate writing higher-order functions using lexical closures. First, let’s look at a simple example of a higher-order function using ‘lexical-let’:

(defun compose (f g)
  (lexical-let ((f f)
                (g g))
    (lambda (x)
      (funcall f (funcall g x)))))

It is a chore to write the ‘lexical-let’ part of it, but ‘defmacro’ can help.

;; Defun with lexically-scoped parameters.  Could also be called
;; lexical-defun.
(defmacro lexdef (name args &rest body)
   `(defun ,name ,args
      (lexical-let ,(mapcar (lambda (arg) (list arg arg))
                            (filter (lambda (a) (not (equal a '&rest))) 
                                    args))
        ,@body)))

Now we can write:

(lexdef compose (f g)
        (lambda (x)
          (funcall f (funcall g x))))

Our macro can also help us write a higher-order function that does currying, i.e., making a new function from ‘f’ by filling in some of ‘f’s arguments and allowing the rest to be provided later.

(lexdef curry (f &rest args)
        (lambda (&rest more-args)
          (apply f (append args more-args))))

(set 'add1 (curry '+ 1))
(assert (= (funcall add1 2) 3))

See also WikiPedia:Scope (programming)


CategoryCode CategoryHistory