compile-file performs compilation of
forms in a file following the rules specified in Section 3.2.2 (Compilation Semantics),
and produces an output file that can be loaded by using
Normally, the top level forms appearing in a file compiled with
compile-file are evaluated only when the resulting
compiled file is loaded, and not when the file is compiled. However,
it is typically the case that some forms in the file need to be evaluated
at compile time so the
remainder of the file can be read and compiled correctly.
eval-when special form can be used to control
whether a top level form is evaluated at compile time, load
time, or both. It is possible to specify any of three situations with
eval-when, denoted by the symbols :compile-toplevel,
:load-toplevel, and :execute. For top level
eval-when forms, :compile-toplevel specifies that the
compiler must evaluate the body at compile time, and
:load-toplevel specifies that the compiler must arrange to evaluate
the body at load time. For non-top level
:execute specifies that the body must be executed in the run-time
The behavior of this form can be more precisely understood in
terms of a model of how
compile-file processes forms in
a file to be compiled. There are two processing modes, called
“not-compile-time” and “compile-time-too”.
Successive forms are read from the file by
and processed in not-compile-time mode; in this mode,
compile-file arranges for forms to be evaluated only at load time
and not at compile time. When
compile-file is in
compile-time-too mode, forms are evaluated both at compile time and
Processing of top level forms in the file compiler is defined as follows:
notinlinedeclaration), the implementation might or might not choose to compute the compiler macro expansion of the form and, having performed the expansion, might or might not choose to process the result as a top level form in the same processing mode (compile-time-too or not-compile-time). If it declines to obtain or use the expansion, it must process the original form.
prognform, each of its body forms is sequentially processed as a top level form in the same processing mode.
compile-fileestablishes the appropriate bindings and processes the body forms as top level forms with those bindings in effect in the same processing mode. (Note that this implies that the lexical environment in which top level forms are processed is not necessarily the null lexical environment.)
eval-whenform, it is handled according to the next figure.
Figure 3.7: EVAL-WHEN processing
Column CT indicates whether :compile-toplevel is specified. Column LT indicates whether :load-toplevel is specified. Column E indicates whether :execute is specified. Column Mode indicates the processing mode; a dash (—) indicates that the processing mode is not relevant.
The Action column specifies one of three actions:
The New Mode column indicates the new processing mode. A dash (—) indicates the compiler remains in its current mode.
Note that top level forms are 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 macro expansion) of subforms that are not top level forms and the order of further compilation is unspecified as long as Common Lisp semantics are preserved.
eval-when forms cause compile-time evaluation only at
top level. Both :compile-toplevel and :load-toplevel situation specifications
are ignored for non-top-level forms. For non-top-level forms,
specifying the :execute situation is treated as an implicit progn
including the forms in the body of the
otherwise, the forms in the body are ignored.
Defining macros (such as
appearing within a file being processed by
normally have compile-time side effects which affect how subsequent forms
in the same file are compiled. A convenient model for explaining how these
side effects happen is that the defining macro expands into one or
eval-when forms, and that the calls which cause the compile-time
side effects to happen appear
in the body of an
(eval-when (:compile-toplevel) ...) form.
The compile-time side effects may cause information about the definition to be stored differently than if the defining macro had been processed in the `normal' way (either interpretively or by loading the compiled file).
In particular, the information stored by the defining macros at compile time
might or might not be available to the interpreter (either during or after compilation),
or during subsequent calls to the compiler. For example,
the following code is nonportable because it assumes that the compiler
stores the macro definition of
foo where it is available to the interpreter:
(defmacro foo (x) `(car ,x)) (eval-when (:execute :compile-toplevel :load-toplevel) (print (foo '(a b c))))
A portable way to do the same thing would be to include the macro
definition inside the
eval-when form, as in:
(eval-when (:execute :compile-toplevel :load-toplevel) (defmacro foo (x) `(car ,x)) (print (foo '(a b c))))
The next figure lists macros that make definitions
available both in the compilation and run-time environments.
It is not specified whether definitions made available in the
compilation environment are available in the evaluation
environment, nor is it specified whether they are available
in subsequent compilation units or subsequent invocations of the
compiler. As with
eval-when, these compile-time side
effects happen only when the defining macros appear at
Figure 3.8: Defining Macros That Affect the Compile-Time Environment
Except where explicitly stated otherwise, no macro defined in the Common Lisp standard produces an expansion that could cause any of the subforms of the macro form to be treated as top level forms. If an implementation also provides a special operator definition of a Common Lisp macro, the special operator definition must be semantically equivalent in this respect.
Compiler macro expansions must also have the same top level evaluation semantics as the form which they replace. This is of concern both to conforming implementations and to conforming programs.