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.
setf
methods must also be available at
compile time.)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.
inline
in the compile-time environment will retain the same
definitions at run time.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.)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.inline
.ftype
information available
will not change.defconstant
in the compile-time environment.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 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-expansion
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