Common Lisp the Language, 2nd Edition

Next: Similarity of Constants Up: The Compiler Previous: Compiled Functions

## 25.1.3. Compilation Environment

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