Common Lisp the Language, 2nd Edition

Next: Documentation Up: The Compiler Previous: Compilation Environment

## 25.1.4. Similarity of Constants

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:
  - S is accessible in `*package*` at compile time and S' is accessible in `*package*` at load time.
  - S' is accessible in the package that is similar as a constant to the home package of symbol S.
  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`.

Next: Documentation Up: The Compiler Previous: Compilation Environment