Previous Next Contents

12. Dynamic Scoping

The let and let* forms provide lexical scoping, which is what you expect if you're used to programming in C or Pascal. Dynamic scoping is what you get in BASIC: if you assign a value to a dynamically scoped variable, every mention of that variable returns that value until you assign another value to the same variable.

In LISP, dynamically scoped variables are called special variables. You can declare a special variable with the defvar special form. Here are some examples of lexically and dynamically scoped variables.

In this example, the function check-regular references a regular (ie, lexically scoped) variable. Since check-regular is lexically outside of the let which binds regular, check-regular returns the variable's global value.

> (set 'regular 5)    ;setq would make it special in CMUCL!
5 
> (defun check-regular () regular)
CHECK-REGULAR 
> (check-regular)
5 
> (let ((regular 6)) (check-regular))
5

In this example, the function check-special references a special (ie, dynamically scoped) variable. Since the call to check-special is temporally inside of the let which binds special, check-special returns the variable's local value.

> (defvar *special* 5)
*SPECIAL*
> (defun check-special () *special*)
CHECK-SPECIAL
> (check-special)
5
> (let ((*special* 6)) (check-special))
6

By convention, the name of a special variable begins and ends with a *. Special variables are chiefly used as global variables, since programmers usually expect lexical scoping for local variables and dynamic scoping for global variables.

For more information on the difference between lexical and dynamic scoping, see Common LISP: the Language.


Previous Next Contents