Common Lisp the Language, 2nd Edition


next up previous contents index
Next: Similarity of Constants Up: The Compiler Previous: Compiled Functions

25.1.3. Compilation Environment

change_begin
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.

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 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.


change_end



next up previous contents index
Next: Similarity of Constants Up: The Compiler Previous: Compiled Functions


AI.Repository@cs.cmu.edu