Next: , Previous: , Up: Scoping Rules for Variable Bindings   [Contents][Index]

12.10.2 Dynamic Binding

Local variable bindings are dynamic in the modern Lisp dialect for special variables (see below), and for all variables in the old Lisp dialect. (See Selecting Lisp Dialect.) Dynamic variable bindings have their uses but are in general more error-prone and less efficient than lexical bindings, and the compiler is less able to find mistakes in code using dynamic bindings.

When a variable is dynamically bound, its current binding at any point in the execution of the Lisp program is simply the most recently-created dynamic local binding for that symbol, or the global binding if there is no such local binding.

Dynamic bindings have dynamic scope and extent, as shown by the following example:

(defvar x -99)  ; x receives an initial value of -99.

(defun getx ()
  x)            ; x is used free in this function.

(let ((x 1))    ; x is dynamically bound.
  (getx))
     ⇒ 1

;; After the let form finishes, x reverts to its
;; previous value, which is -99.

(getx)
     ⇒ -99

The function getx refers to x. This is a free reference, in the sense that there is no binding for x within that defun construct itself. When we call getx from within a let form in which x is (dynamically) bound, it retrieves the local value (i.e., 1). But when we call getx outside the let form, it retrieves the global value (i.e., -99).

Here is another example, which illustrates setting a dynamically bound variable using setq:

(defvar x -99)      ; x receives an initial value of -99.

(defun addx ()
  (setq x (1+ x)))  ; Add 1 to x and return its new value.

(let ((x 1))
  (addx)
  (addx))
     ⇒ 3           ; The two addx calls add to x twice.

;; After the let form finishes, x reverts to its
;; previous value, which is -99.

(addx)
     ⇒ -98

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 (see Defining Global Variables). All other variables are subject to lexical binding.

Using defvar without a value, it is possible to bind a variable dynamically just in one file, or in just one part of a file while still binding it lexically elsewhere. For example:

(let (_)
  (defvar x)      ; Let-bindings of x will be dynamic within this let.
  (let ((x -99))  ; This is a dynamic binding of x.
    (defun get-dynamic-x ()
      x)))

(let ((x 'lexical)) ; This is a lexical binding of x.
  (defun get-lexical-x ()
    x))

(let (_)
  (defvar x)
  (let ((x 'dynamic))
    (list (get-lexical-x)
          (get-dynamic-x))))
    ⇒ (lexical dynamic)
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.

Note that since this is a function, it can only return non-nil for variables which are permanently special, but not for those that are only special in the current lexical scope.

The use of a special variable as a formal argument in a function is not supported.

Dynamic binding is implemented in Emacs Lisp in a simple way. Each symbol has a value cell, which specifies its current dynamic value (or absence of value). See Symbol Components. When a symbol is given a dynamic local binding, Emacs records the contents of the value cell (or absence thereof) in a stack, and stores the new local value in the value cell. When the binding construct finishes executing, Emacs pops the old value off the stack, and puts it in the value cell.

Next: Proper Use of Dynamic Binding, Previous: Lexical Binding, Up: Scoping Rules for Variable Bindings   [Contents][Index]