name—a symbol; not evaluated.
defparameter, it is always evaluated,
defvar it is evaluated
only if name is not already bound.
documentation—a string; not evaluated.
defvar establish name
as a dynamic variable.
assigns the initial-value to the dynamic variable named name.
defvar, by contrast, assigns initial-value (if supplied)
to the dynamic variable named name
only if name is not already bound.
If no initial-value is supplied,
defvar leaves the value cell of
the dynamic variable named name undisturbed;
if name was previously bound, its old value persists,
and if it was previously unbound, it remains unbound.
If documentation is supplied, it is attached to name as a documentation string of kind variable.
defvar normally appear as a top level form,
but it is meaningful for them to appear as non-top-level forms. However,
the compile-time side effects described below only take place when
they appear as top level forms.
(defparameter *p* 1) → *P* *p* → 1 (constantp '*p*) → false (setq *p* 2) → 2 (defparameter *p* 3) → *P* *p* → 3 (defvar *v* 1) → *V* *v* → 1 (constantp '*v*) → false (setq *v* 2) → 2 (defvar *v* 3) → *V* *v* → 2 (defun foo () (let ((*p* 'p) (*v* 'v)) (bar))) → FOO (defun bar () (list *p* *v*)) → BAR (foo) → (P V)
The principal operational distinction between
defparameter makes an unconditional assignment to name,
defvar makes a conditional one. In practice, this means that
defparameter is useful in situations where loading or reloading the definition
would want to pick up a new value of the variable, while
defvar is used in
situations where the old value would want to be retained if the file were loaded or reloaded.
For example, one might create a file which contained:
(defvar *the-interesting-numbers* '()) (defmacro define-interesting-number (name n) `(progn (defvar ,name ,n) (pushnew ,name *the-interesting-numbers*) ',name)) (define-interesting-number *my-height* 168) ;cm (define-interesting-number *my-weight* 13) ;stones
Here the initial value,
(), for the variable
is just a seed that we are never likely to want to reset to something else
once something has been grown from it. As such, we have used
to avoid having the
*interesting-numbers* information reset if the file is
loaded a second time. It is true that the two calls to
define-interesting-number here would be reprocessed, but
if there were additional calls in another file, they would not be and that
information would be lost. On the other hand, consider the following code:
(defparameter *default-beep-count* 3) (defun beep (&optional (n *default-beep-count*)) (dotimes (i n) (si:%beep 1000. 100000.) (sleep 0.1)))
Here we could easily imagine editing the code to change the initial value of
*default-beep-count*, and then reloading the file to pick up the new value.
In order to make value updating easy, we have used
On the other hand, there is potential value to using
defvar in this
situation. For example, suppose that someone had predefined an alternate
*default-beep-count*, or had loaded the file and then manually
changed the value. In both cases, if we had used
defvar instead of
defparameter, those user preferences would not be overridden by
(re)loading the file.
The choice of whether to use
visible consequences to programs, but is nevertheless often made for subjective
defparameter form appears as a top level form,
the compiler must recognize that the name has been
special. However, it must neither evaluate
the initial-value form nor assign the
dynamic variable named name at compile time.
There may be additional (implementation-defined) compile-time or run-time side effects, as long as such effects do not interfere with the correct operation of conforming programs.
defvar is affected by whether name is already bound.
declaim, defconstant, documentation, Section 3.2 (Compilation)
It is customary to name dynamic variables with an asterisk
at the beginning and end of the name. e.g.,
*foo* is a good name for
a dynamic variable, but not for a lexical variable;
foo is a good name for a lexical variable,
but not for a dynamic variable.
This naming convention is observed for all defined names in Common Lisp;
however, neither conforming programs nor conforming implementations
are obliged to adhere to this convention.
The intent of the permission for additional side effects is to allow
implementations to do normal “bookkeeping” that accompanies
definitions. For example, the macro expansion of a
defparameter form might include code that arranges to
record the name of the source file in which the definition occurs.
defvar might be defined as follows:
(defmacro defparameter (name initial-value &optional (documentation nil documentation-p)) `(progn (declaim (special ,name)) (setf (symbol-value ',name) ,initial-value) ,(when documentation-p `(setf (documentation ',name 'variable) ',documentation)) ',name)) (defmacro defvar (name &optional (initial-value nil initial-value-p) (documentation nil documentation-p)) `(progn (declaim (special ,name)) ,(when initial-value-p `(unless (boundp ',name) (setf (symbol-value ',name) ,initial-value))) ,(when documentation-p `(setf (documentation ',name 'variable) ',documentation)) ',name))