Common Lisp the Language, 2nd Edition


next up previous contents index
Next: Documentation Up: The Compiler Previous: Compilation Environment

25.1.4. Similarity of Constants

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

number

Two numbers are similar as constants if they are of the same type and represent the same mathematical value.

character

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

symbol
X3J13 voted in June 1989 (COMPILE-FILE-SYMBOL-HANDLING)   to define similarity as a constant for interned symbols. A symbol S appearing in the source code is similar as a constant to a symbol S' in the compiled code if their print names are similar as constants and either of the following conditions holds: The ``similar as constants'' relationship for interned symbols has nothing to do with *readtable* or how the function read would parse the characters in the print name of the symbol.

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.

package

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.

random-state

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

cons

Two conses are similar as constants if the values of their respective car and cdr attributes are similar as constants.

array

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.

hash-table

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.

pathname

Two pathnames are similar as constants if all corresponding pathname components are similar as constants.

stream, readtable, and method

Objects of these types are not supported in compiled constants.

function

X3J13 voted in June 1989 (CONSTANT-FUNCTION-COMPILATION)   to specify that objects of type function are not supported in compiled constants.

structure and standard-object

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.


Rationale: Objects of type symbol and package cannot be coalesced because the fact that they are named, interned objects means they are already as coalesced as it is useful for them to be. Uninterned symbols could perhaps be coalesced, but that was thought to be more dangerous than useful. Structures and objects could be coalesced if a ``similar as a constant'' predicate were defined for them; it would be a generic function. However, at present there is no such predicate. Currently make-load-form provides a protocol by which compile-file and load work together to construct an object in the compiled code that is equivalent to the object in the source code; a different mechanism would have to be added to permit coalescing.

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



next up previous contents index
Next: Documentation Up: The Compiler Previous: Compilation Environment


AI.Repository@cs.cmu.edu