Common Lisp the Language, 2nd Edition


next up previous contents index
Next: Determining the Class Up: Programmer Interface Concepts Previous: Examples

28.1.4. Integrating Types and Classes

change_begin
The Common Lisp Object System maps the space of classes into the Common Lisp type space. Every class that has a proper name has a corresponding type with the same name.

The proper name of every class is a valid type specifier. In addition, every class object is a valid type specifier. Thus the expression (typep object class) evaluates to true if the class of object is class itself or a subclass of class. The evaluation of the expression (subtypep class1 class2) returns the values t and t if class1 is a subclass of class2 or if they are the same class; otherwise it returns the values nil and t. If I is an instance of some class C named S and C is an instance of standard-class, the evaluation of the expression (type-of I) will return S if S is the proper name of C; if S is not the proper name of C, the expression (type-of I) will return C.

Because the names of classes and class objects are type specifiers, they may be used in the special form the and in type declarations.

Many but not all of the predefined Common Lisp type specifiers have a corresponding class with the same proper name as the type. These type specifiers are listed in table 28-1. For example, the type array has a corresponding class named array. No type specifier that is a list, such as (vector double-float 100), has a corresponding class. The form deftype does not create any classes.

Each class that corresponds to a predefined Common Lisp type specifier can be implemented in one of three ways, at the discretion of each implementation. It can be a standard class (of the kind defined by defclass), a structure class (defined by defstruct), or a built-in class (implemented in a special, non-extensible way).

A built-in class is one whose instances have restricted capabilities or special representations. Attempting to use defclass to define subclasses of a built-in class signals an error. Calling make-instance to create an instance of a built-in class signals an error. Calling slot-value on an instance of a built-in class signals an error. Redefining a built-in class or using change-class to change the class of an instance to or from a built-in class signals an error. However, built-in classes can be used as parameter specializers in methods.

It is possible to determine whether a class is a built-in class by checking the metaclass. A standard class is an instance of standard-class, a built-in class is an instance of built-in-class, and a structure class is an instance of structure-class.

Each structure type created by defstruct without using the :type option has a corresponding class. This class is an instance of structure-class.

The :include option of defstruct creates a direct subclass of the class that corresponds to the included structure.

The purpose of specifying that many of the standard Common Lisp type specifiers have a corresponding class is to enable users to write methods that discriminate on these types. Method selection requires that a class precedence list can be determined for each class.

The hierarchical relationships among the Common Lisp type specifiers are mirrored by relationships among the classes corresponding to those types. The existing type hierarchy is used for determining the class precedence list for each class that corresponds to a predefined Common Lisp type. In some cases, the first edition did not specify a local precedence order for two supertypes of a given type specifier. For example, null is a subtype of both symbol and list, but the first edition did not specify whether symbol is more specific or less specific than list. The CLOS specification defines those relationships for all such classes.

Table 28-1 lists the set of classes required by the Object System that correspond to predefined Common Lisp type specifiers. The superclasses of each such class are presented in order from most specific to most general, thereby defining the class precedence list for the class. The local precedence order for each class that corresponds to a Common Lisp type specifier can be derived from this table.

Individual implementations may be extended to define other type specifiers to have a corresponding class. Individual implementations can be extended to add other subclass relationships and to add other elements to the class precedence lists in the above table as long as they do not violate the type relationships and disjointness requirements specified in section 2.15. A standard class defined with no direct superclasses is guaranteed to be disjoint from all of the classes in the table, except for the class named t.

[At this point the original CLOS report specified that certain Common Lisp types were to appear in table 28-1 if and only if X3J13 voted to make them disjoint from cons, symbol, array, number, and character. X3J13 voted to do so in June 1988 (DATA-TYPES-HIERARCHY-UNDERSPECIFIED)   . I have added these types and their class precedence lists to the table; the new types are indicated by asterisks.-GLS]

 
----------------------------------------------------------------
Table 28-1: Class Precedence Lists for Predefined Types

Predefined              Class Precedence List 
Common Lisp Type        for Corresponding Class
==============================================================
array                   (array t)
bit-vector              (bit-vector vector array sequence t)
character               (character t)
complex                 (complex number t)
cons                    (cons list sequence t)
float                   (float number t)
function *              (function t) 
hash-table *            (hash-table t) 
integer                 (integer rational number t)
list                    (list sequence t)
null                    (null symbol list sequence t)
number                  (number t)
package *               (package t) 
pathname *              (pathname t) 
random-state *          (random-state t) 
ratio                   (ratio rational number t)
rational                (rational number t)
readtable *             (readtable t) 
sequence                (sequence t)
stream *                (stream t) 
string                  (string vector array sequence t)
symbol                  (symbol t)
t                       (t)
vector                  (vector array sequence t)
==============================================================

[An asterisk indicates a type added to this table as a consequence of
a portion of the CLOS specification that was conditional on X3J13
voting to make that type disjoint from certain other built-in types
(DATA-TYPES-HIERARCHY-UNDERSPECIFIED).---GLS]

----------------------------------------------------------------

change_end



next up previous contents index
Next: Determining the Class Up: Programmer Interface Concepts Previous: Examples


AI.Repository@cs.cmu.edu