Common Lisp the Language, 2nd Edition
X3J13
voted in March 1989 (CONSTANT-COMPILABLE-TYPES)
to specify what objects can be in compiled constants and
what relationship there must be between a constant
passed to the compiler and the one that is established by compiling it
and then loading its file.
The key is a definition of an equivalence relationship called ``similarity as constants'' between Lisp objects. Code passed through the file compiler and then loaded must behave as though quoted constants in it are similar in this sense to quoted constants in the corresponding source code. An object may be used as a quoted constant processed by compile-file if and only if the compiler can guarantee that the resulting constant established by loading the compiled file is ``similar as a constant'' to the original. Specific requirements are spelled out below.
Some types of objects, such as streams, are not supported in constants processed by the file compiler. Such objects may not portably appear as constants in code processed with compile-file. Conforming implementations are required to handle such objects either by having the compiler or loader reconstruct an equivalent copy of the object in some implementation-specific manner or by having the compiler signal an error.
Of the types supported in constants, some are treated as aggregate objects. For these types, being similar as constants is defined recursively. We say that an object of such a type has certain ``basic attributes''; to be similar as a constant to another object, the values of the corresponding attributes of the two objects must also be similar as constants.
A definition of this recursive form has problems with any circular or infinitely recursive object such as a list that is an element of itself. We use the idea of depth-limited comparison and say that two objects are similar as constants if they are similar at all finite levels. This idea is implicit in the definitions below, and it applies in all the places where attributes of two objects are required to be similar as constants. The question of handling circular constants is the subject of a separate vote by X3J13 (see below).
The following terms are used throughout this section. The term constant refers to a quoted or self-evaluating constant, not a named constant defined by defconstant. The term source code is used to refer to the objects constructed when compile-file calls read (or the equivalent) and to additional objects constructed by macro expansion during file compilation. The term compiled code is used to refer to objects constructed by load.
Two objects are similar as a constant if and only if they are both of one of the types listed below and satisfy the additional requirements listed for that type.
Two numbers are similar as constants if they are of the same type and represent the same mathematical value.
Two characters are similar as constants if they both represent the same character. (The intent is that this be compatible with how eql is defined on characters.)
An uninterned symbol in the source code is similar as a constant to an uninterned symbol in the compiled code if their print names are similar as constants.
A package in the source code is similar as a constant to a package in the compiled code if their names are similar as constants. Note that the loader finds the corresponding package object as if by calling find-package with the package name as an argument. An error is signaled if no package of that name exists at load time.
We say that two random-state objects are functionally equivalent if applying random to them repeatedly always produces the same pseudo-random numbers in the same order.
Two random-states are similar as constants if and only if copies of them made via make-random-state are functionally equivalent. (Note that a constant random-state object cannot be used as the state argument to the function random because random performs a side effect on that argument.)
Two conses are similar as constants if the values of their respective car and cdr attributes are similar as constants.
Two arrays are similar as constants if the corresponding values of each of the following attributes are similar as constants: for vectors (one-dimensional arrays), the length and element-type and the result of elt for all valid indices; for all other arrays, the array-rank, the result of array-dimension for all valid axis numbers, the array-element-type, and the result of aref for all valid indices. (The point of distinguishing vectors is to take any fill pointers into account.)
If the array in the source code is a simple-array, then the corresponding array in the compiled code must also be a simple-array, but if the array in the source code is displaced, has a fill pointer, or is adjustable, the corresponding array in the compiled code is permitted to lack any or all of these qualities.
Two hash tables are similar as constants if they meet three requirements. First, they must have the same test (for example, both are eql hash tables or both are equal hash tables). Second, there must be a unique bijective correspondence between the keys of the two tables, such that the corresponding keys are similar as constants. Third, for all keys, the values associated with two corresponding keys must be similar as constants.
If there is more than one possible one-to-one correspondence between the keys of the two tables, it is unspecified whether the two tables are similar as constants. A conforming program cannot use such a table as a constant.
Two pathnames are similar as constants if all corresponding pathname components are similar as constants.
Objects of these types are not supported in compiled constants.
X3J13 voted in June 1989 (CONSTANT-FUNCTION-COMPILATION) to specify that objects of type function are not supported in compiled constants.
X3J13 voted in March 1989 (LOAD-OBJECTS) to introduce a facility based on the Common Lisp Object System whereby a user can specify how compile-file and load must cooperate to reconstruct compile-time constant objects at load time (see make-load-form).
X3J13 voted in March 1989 (CONSTANT-COLLAPSING) to specify the circumstances under which constants may be coalesced in compiled code.
Suppose A and B are two objects used as quoted constants in the source code, and that A' and B' are the corresponding objects in the compiled code. If A' and B' are eql but A and B were not eql, then we say that A and B have been coalesced by the compiler.
An implementation is permitted to coalesce constants appearing in code to be compiled if and only if they are similar as constants, except that objects of type symbol, package, structure, or standard-object obey their own rules and may not be coalesced by a separate mechanism.
Note that coalescing is possible only because it is forbidden to destructively modify constants (CONSTANT-MODIFICATION) (see quote).
X3J13 voted in March 1989 (CONSTANT-CIRCULAR-COMPILATION) to specify
that objects containing circular or infinitely recursive references may legitimately
appear as constants to be compiled. The compiler is
required to preserve eql-ness of substructures within a file compiled
by compile-file.