5.3 Top-Level Forms

The standard way for the user to interact with a Common Lisp implementation is via a read-eval-print loop: the system repeatedly reads a form from some input source (such as a keyboard or a disk file), evaluates it, and then prints the value(s) to some output sink (such as a display screen or another disk file). Any form (evaluable data object) is acceptable; however, certain special operators are specifically designed to be convenient for use as top-level forms, rather than as forms embedded within other forms in the way that (+ 3 4) is embedded within (if p (+ 3 4) 6). These top-level special operators may be used to define globally named functions, to define macros, to make declarations, and to define global values for special variables.

While defining forms normally appear at top level, it is meaningful to place them in non-top-level contexts. All defining forms that create functional objects from code appearing as argument forms must ensure that such argument forms refer to the enclosing lexical environment. Compilers must handle defining forms properly in all situations, not just top-level contexts. However, certain compile-time side effects of these defining forms are performed only when the defining forms occur at top level (see section 24.1).

Macros are usually defined by using the special operator defmacro. This facility is fairly complicated; it is described in chapter 8.

5.3.1 Defining Named Functions

The defun special operator is the usual means of defining named functions.

[Macro] defun name lambda-list [[{declaration}* | doc-string]] {form}*

Evaluating a defun form causes the symbol name to be a global name for the function specified by the lambda-expression

(lambda lambda-list {declaration | doc-string}* {form}* )

defined in the lexical environment in which the defun form was executed. Because defun forms normally appear at top level, this is normally the null lexical environment.

While defining forms normally appear at top level, it is meaningful to place them in non-top-level contexts; defun must define the function within the enclosing lexical environment, not within the null lexical environment.

defun can accept any function-name (a symbol or a list whose car is setf—see section 7.1) as a name. Thus one may write

(defun (setf cadr) ...)

to define a setf expansion function for cadr (although it may be much more convenient to use defsetf or define-modify-macro).

If the optional documentation string doc-string is present, then it is attached to the name as a documentation string of type function; see documentation. If doc-string is not followed by a declaration, it may be present only if at least one form is also specified, as it is otherwise taken to be a form. It is an error if more than one doc-string is present.

The forms constitute the body of the defined function; they are executed as an implicit progn.

The body of the defined function is implicitly enclosed in a block construct whose name is the same as the name of the function. Therefore return-from may be used to exit from the function.

Other implementation-dependent bookkeeping actions may be taken as well by defun. The name is returned as the value of the defun form. For example:

(defun discriminant (a b c)
  (declare (number a b c))
  "Compute the discriminant for a quadratic equation.
   Given a, b, and c, the value b̂2-4*a*c is calculated.
   If the coefficients a, b, and c are all real (that is,
   not complex), then the quadratic equation a*x̂2+b*x+c=0
   has real, multiple, or complex roots depending on
   whether this calculated value is positive, zero, or
   negative, respectively."   (- (* b b) (* 4 a c)))
    discriminant
   and now (discriminant 1 2/3 -2)  76/9

It is permissible to use defun to redefine a function, to install a corrected version of an incorrect definition, for example. It is permissible to redefine a macro as a function. It is an error to attempt to redefine the name of a special form (see table 5.1) as a function.


5.3.2 Declaring Global Variables and Named Constants

The defvar and defparameter special operators are the usual means of specifying globally defined variables. The defconstant special operator is used for defining named constants.

[Macro] defvar name [initial-value [documentation]]

[Macro] defparameter name initial-value [documentation]

[Macro] defconstant name initial-value [documentation]

defvar is the recommended way to declare the use of a special variable in a program.

(defvar variable)

proclaims variable to be special (see proclaim), and may perform other system-dependent bookkeeping actions.

If no initial-value form is provided, defvar does not change the value of the variable; if no initial-value form is provided and the variable has no value, defvar does not give it a value.

If a second argument form is supplied,

(defvar variable initial-value)

then variable is initialized to the result of evaluating the form initial-value unless it already has a value. The initial-value form is not evaluated unless it is used; this fact is useful if evaluation of the initial-value form does something expensive like creating a large data structure.

X3J13 voted in June 1987 to clarify that evaluation of the initial-value and the initialization of the variable occur, if at all, at the time the defvar form is executed, and that the initial-value form is evaluated if and only if the variable does not already have a value.

The initialization is performed by assignment and thus assigns a global value to the variable unless there are currently special bindings of that variable. Normally there should not be any such special bindings.

defvar also provides a good place to put a comment describing the meaning of the variable, whereas an ordinary special proclamation offers the temptation to declare several variables at once and not have room to describe them all.

(defvar *visible-windows* 0
  "Number of windows at least partially visible on the screen")

defparameter is similar to defvar, but defparameter requires an initial-value form, always evaluates the form, and assigns the result to the variable. The semantic distinction is that defvar is intended to declare a variable changed by the program, whereas defparameter is intended to declare a variable that is normally constant but can be changed (possibly at run time), where such a change is considered a change to the program. defparameter therefore does not indicate that the quantity never changes; in particular, it does not license the compiler to build assumptions about the value into programs being compiled.

defconstant is like defparameter but does assert that the value of the variable name is fixed and does license the compiler to build assumptions about the value into programs being compiled. (However, if the compiler chooses to replace references to the name of the constant by the value of the constant in code to be compiled, perhaps in order to allow further optimization, the compiler must take care that such “copies” appear to be eql to the object that is the actual value of the constant. For example, the compiler may freely make copies of numbers but must exercise care when the value is a list.)

It is an error if there are any special bindings of the variable at the time the defconstant form is executed (but implementations may or may not check for this).

Once a name has been declared by defconstant to be constant, any further assignment to or binding of that special variable is an error. This is the case for such system-supplied constants as t and most-positive-fixnum. A compiler may also choose to issue warnings about bindings of the lexical variable of the same name.

X3J13 voted in January 1989 to clarify the preceding paragraph by specifying that it is an error to rebind constant symbols as either lexical or special variables. Consequently, a valid reference to a symbol declared with defconstant always refers to its global value. (Unfortunately, this violates the principle of referential transparency, for one cannot always choose names for lexical variables without regard to surrounding context.)

For any of these constructs, the documentation should be a string. The string is attached to the name of the variable, parameter, or constant under the variable documentation type; see the documentation function.

The documentation-string is not evaluated but must appear as a literal string when the defvar, defparameter, or defconstant form is evaluated.

For example, the form

(defvar *avoid-registers* nil "Compilation control switch #43")

is legitimate, but

(defvar *avoid-registers* nil
  (format nil "Compilation control switch #~D"
          (incf *compiler-switch-number*)))

is erroneous because the call to format is not a literal string.

(On the other hand, the form

(defvar *avoid-registers* nil
  #.(format nil "Compilation control switch #~D"
            (incf *compiler-switch-number*)))

might be used to accomplish the same purpose, because the call to format is evaluated at read time; when the defvar form is evaluated, only the result of the call to format, a string, appears in the defvar form.)

These constructs are normally used only as top-level forms. The value returned by each of these constructs is the name declared.


5.3.3 Control of Time of Evaluation

[Special operator] eval-when ({situation}*) {form}*

The body of an eval-when form is processed as an implicit progn, but only in the situations listed. Each situation must be a symbol, either :compile-toplevel, :load-toplevel, or :execute.

The use of :compile-toplevel and :load-toplevel controls whether and when processing occurs for top-level forms. The use of :execute controls whether processing occurs for non-top-level forms.

The eval-when construct may be more precisely understood in terms of a model of how the file compiler, compile-file, processes forms in a file to be compiled.

Successive forms are read from the file by the file compiler using read. These top-level forms are normally processed in what we call “not-compile-time” mode. There is one other mode, called “compile-time-too” mode, which can come into play for top-level forms. The eval-when special operator is used to annotate a program in a way that allows the program doing the processing to select the appropriate mode.

Processing of top-level forms in the file compiler works as follows:

Note that top-level forms are guaranteed to be processed in the order in which they textually appear in the file, and that each top-level form read by the compiler is processed before the next is read. However, the order of processing (including, in particular, macro expansion) of subforms that are not top-level forms is unspecified.

For an eval-when form that is not a top-level form in the file compiler (that is, either in the interpreter, in compile, or in the file compiler but not at top level), if the :execute situation is specified, its body is treated as an implicit progn. Otherwise, the body is ignored and the eval-when form has the value nil.

For the sake of backward compatibility, a situation may also be compile, load, or eval. Within a top-level eval-when form these have the same meaning as :compile-toplevel, :load-toplevel, and :execute, respectively; but their effect is undefined when used in an eval-when form that is not at top level.

The following effects are logical consequences of the preceding specification:

Here are some additional examples.

(let ((x 1))
  (eval-when (:execute :load-toplevel :compile-toplevel)
    (setf (symbol-function ’foo1) #’(lambda () x))))

The eval-when in the preceding expression is not at top level, so only the :execute keyword is considered. At compile time, this has no effect. At load time (if the let is at top level), or at execution time (if the let is embedded in some other form which does not execute until later), this sets (symbol-function ’foo1) to a function that returns 1.

(eval-when (:execute :load-toplevel :compile-toplevel)
  (let ((x 2))
    (eval-when (:execute :load-toplevel :compile-toplevel)
      (setf (symbol-function ’foo2) #’(lambda () x)))))

If the preceding expression occurs at the top level of a file to be compiled, it has both a compile time and a load-time effect of setting (symbol-function ’foo2) to a function that returns 2.

(eval-when (:execute :load-toplevel :compile-toplevel)
  (setf (symbol-function ’foo3) #’(lambda () 3)))

If the preceding expression occurs at the top level of a file to be compiled, it has both a compile time and a load-time effect of setting the function cell of foo3 to a function that returns 3.

(eval-when (:compile-toplevel)
  (eval-when (:compile-toplevel)
    (print ’foo4)))

The preceding expression always does nothing; it simply returns nil.

(eval-when (:compile-toplevel)
  (eval-when (:execute)
    (print ’foo5)))

If the preceding form occurs at the top level of a file to be compiled, foo5 is printed at compile time. If this form occurs in a non-top-level position, nothing is printed at compile time. Regardless of context, nothing is ever printed at load time or execution time.

(eval-when (:execute :load-toplevel)
  (eval-when (:compile-toplevel)
    (print ’foo6)))

If the preceding form occurs at the top level of a file to be compiled, foo6 is printed at compile time. If this form occurs in a non-top-level position, nothing is printed at compile time. Regardless of context, nothing is ever printed at load time or execution time.