Common Lisp the Language, 2nd Edition
Next: Similarity of Constants
Up: The Compiler
Previous: Compiled Functions
X3J13 voted in June 1989 (COMPILE-ENVIRONMENT-CONSISTENCY)
to specify what information must be available at compile time
for correct compilation
and what need not be available until run time.
The following information must be present in the compile-time
environment for a program to be compiled correctly. This
information need not also be present in the run-time environment.
- In conforming code, macros referenced in the code being compiled
must have been previously defined in the compile-time environment.
The compiler must treat as a function call any form that is a list whose car is
a symbol that does not name a macro or special form.
(This implies that setf methods must also be available at
compile time.)
- In conforming code, proclamations for special variables must
be made in the compile-time environment before any bindings of
those variables are processed by the compiler. The compiler
must treat any binding of an undeclared variable as a lexical
binding.
The compiler may incorporate the following kinds of information
into the code it produces, if the information is present in the
compile-time environment and is referenced within the code being
compiled; however, the compiler is not required to do so.
When compile-time and run-time definitions differ, it is
unspecified which will prevail within the compiled code
(unless some other behavior is explicitly specified below). It is also
permissible for an implementation to signal an error at run time on
detecting such a discrepancy. In all cases, the absence of the
information at compile time is not an error, but its presence may
enable the compiler to generate more efficient code.
- The compiler may assume that functions that are defined and
declared inline in the compile-time environment will retain the
same definitions at run time.
- The compiler may assume that, within a named function, a
recursive call to a function of the same name refers to the
same function, unless that function has been declared notinline.
(This permits tail-recursive calls of a function to itself
to be compiled as jumps, for example, thereby turning certain recursive
schemas into efficient loops.)
- In the absence of notinline
declarations to the contrary,
compile-file may assume that a call within the file being compiled to a named
function that is defined in that file refers to that function.
(This rule permits block compilation of files.) The behavior of
the program is unspecified if functions are redefined individually
at run time.
- The compiler may assume that the signature (or ``interface contract'') of
all built-in Common Lisp functions will not change. In addition,
the compiler may treat all built-in Common Lisp functions as if
they had been proclaimed inline.
- The compiler may assume that the signature (or ``interface contract'') of
functions with ftype information available will not change.
- The compiler may ``wire in'' (that is, open-code or inline)
the values of symbolic constants
that have been defined with defconstant in the compile-time
environment.
- The compiler may assume that any type definition made with defstruct
or deftype in the compile-time environment will retain the same
definition in the run-time environment. It may also assume that
a class defined by defclass in the compile-time environment will
be defined in the run-time environment in such a way as to have
the same superclasses and metaclass. This implies that
subtype/supertype relationships of type specifiers will not
change between compile time and run time. (Note that it is not
an error for an unknown type to appear in a declaration at
compile time, although it is reasonable for the compiler to
emit a warning in such a case.)
- The compiler may assume that if type declarations are present
in the compile-time environment, the corresponding variables and
functions present in the run-time environment will actually be of
those types. If this assumption is violated, the run-time behavior of the program is
undefined.
The compiler must not make any additional assumptions about
consistency between the compile-time and run-time environments. In
particular, the compiler may not assume that functions that are defined
in the compile-time environment will retain either the
same definition or the same signature at run time, except
as described above.
Similarly,
the compiler may not signal an error if it sees a call to a
function that is not defined at compile time, since that function
may be provided at run time.
X3J13 voted in January 1989 (COMPILE-FILE-HANDLING-OF-TOP-LEVEL-FORMS)
to specify the compile-time side effects of processing various macro forms.
Calls to defining macros such as defmacro or defvar appearing
within a file being processed by compile-file normally have
compile-time side effects that affect how subsequent forms in the
same file are compiled. A convenient model for explaining how these
side effects happen is that each defining macro expands into one or
more eval-when forms and that compile-time
side effects are caused by calls occurring in the body of an
(eval-when (:compile-toplevel) ...) form.
The affected defining macros and their specific side effects are
as follows. In each case, it is identified what a user must do to
ensure that a program is conforming, and what a compiler must do
in order to correctly process a conforming program.
- deftype
-
The user must ensure that the body of a deftype form is
evaluable at compile time if the type is referenced in subsequent type
declarations. The compiler must ensure that a type
specifier defined by deftype
is recognized in subsequent type declarations. If the
expansion of a type specifier is not defined fully at compile time
(perhaps because it expands into an unknown type specifier or a
satisfies of a named function that isn't defined in the compile-time
environment), an implementation may ignore any references to this type
in declarations and may signal a warning.
- defmacro and define-modify-macro
-
The compiler must store macro
definitions at compile time, so that occurrences of the macro later on
in the file can be expanded correctly. The user must ensure that the
body of the macro is evaluable at compile time if it is referenced
within the file being compiled.
- defun
-
No required compile-time side effects are associated with defun forms.
In particular, defun does not make the function definition available
at compile time. An implementation may choose to store information
about the function for the purposes of compile-time error checking
(such as checking the number of arguments on calls) or to permit later
inline expansion of the function.
- defvar and defparameter
-
The compiler must recognize that the variables
named by these forms have been proclaimed special. However, it must
not evaluate the initial-value form or set the variable at compile
time.
- defconstant
-
The compiler must recognize that the symbol names a
constant. An implementation may choose to evaluate the value-form at
compile time, load time, or both. Therefore the user must ensure that
the value-form is evaluable at compile time (regardless of whether or
not references to the constant appear in the file) and that it always
evaluates to the same value.
(There has been considerable
variance among implementations on this point. The effect of this specification is
to legitimize all of the implementation variants by requiring care of the user.)
- defsetf and define-setf-method
-
The compiler must make setf methods
available so that they may be used to expand calls to setf later on in
the file. Users must ensure that the body of a call
to define-setf-method or
the complex form of defsetf is evaluable at compile time if the
corresponding place is referred to in a subsequent setf in the same
file. The compiler must make these setf methods available to
compile-time calls to get-setf-method when its environment argument is
a value received as the &environment parameter of a macro.
- defstruct
-
The compiler must make the structure type name recognized
as a valid type name in subsequent declarations (as described above
for deftype) and
make the structure slot accessors known to setf.
In addition, the
compiler must save enough information so that
further defstruct definitions can include (with the :include
option) a structure type defined
earlier in the file being compiled. The functions that defstruct
generates are not defined in the compile-time environment, although
the compiler may save enough information about the functions to allow
inline expansion of
subsequent calls to these functions. The #S reader syntax may or may not be
available for that structure type at compile time.
- define-condition
-
The rules are essentially the same as those for
defstruct. The compiler must make the condition type recognizable as a
valid type name, and it must be possible to reference the condition
type as the parent-type of another condition type in a subsequent
define-condition form in the file being compiled.
- defpackage
-
All of the actions normally performed by the defpackage macro at load
time must also be performed at compile time.
Compile-time side effects may cause information about a
definition to be stored in a different manner from
information about definitions
processed either interpretively or by loading
a compiled file.
In particular, the information stored by a defining macro at
compile time may or may not be available to the interpreter (either
during or after compilation) or during subsequent calls to compile or
compile-file. For example, the following code is not portable 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)))) ;Wrong
The goal may be accomplished portably by including the macro
definition within the eval-when form:
(eval-when (eval compile load)
(defmacro foo (x) `(car ,x))
(print (foo '(a b c)))) ;Right
- declaim
-
X3J13 voted in June 1989 (PROCLAIM-ETC-IN-COMPILE-FILE)
to add a new macro declaim for making proclamations recognizable
at compile time. The declaration specifiers in the declaim form
are effectively proclaimed at compile time so as to affect
compilation of subsequent forms. (Note that compiler processing
of a call to proclaim
does not have any compile-time side effects, for proclaim
is a function.)
- in-package
-
X3J13 voted in March 1989 (IN-PACKAGE-FUNCTIONALITY) to specify that
all of the actions normally performed by the in-package macro at load
time must also be performed at compile time.
X3J13 voted in June 1989 (CLOS-MACRO-COMPILATION)
to specify the compile-time side effects of processing various CLOS-related
macro forms. Top-level calls to the CLOS defining macros have the
following compile-time side effects; any other compile-time behavior
is explicitly left unspecified.
- defclass
-
The class name may appear in subsequent type declarations and
can be used as a specializer in subsequent defmethod forms.
Thus the compile-time behavior of defclass is similar to that of
deftype or defstruct.
- defgeneric
-
The generic function can be referenced in subsequent defmethod forms,
but the compiler does not arrange for the generic function to be callable
at compile time.
- defmethod
-
The compiler does not arrange for the method to be callable at compile
time. If there is a generic function with the same name defined at
compile time, compiling a defmethod form does not add the method to that
generic function; the method is added to the generic
function only when the defmethod form is actually executed.
The error-signaling behavior described in the specification of
defmethod in chapter 28 (if the function isn't a generic function
or if the lambda-list is not congruent) occurs only when the defining
form is executed, not at compile time.
The forms in eql parameter specializers are evaluated when the defmethod
form is executed. The compiler is permitted to build in knowledge
about what the form in an eql specializer will evaluate to in cases
where the ultimate result can be syntactically inferred without
actually evaluating it.
- define-method-combination
-
The method combination can be used in subsequent defgeneric forms.
The body of a define-method-combination form is evaluated no earlier
than when the defining macro is executed and possibly as late as
generic function invocation time. The compiler may attempt to
evaluate these forms at compile time but must not depend on being able
to do so.
Next: Similarity of Constants
Up: The Compiler
Previous: Compiled Functions
AI.Repository@cs.cmu.edu