Greg Pfeil's Class Hierarchy diagram provides a comprehensive picture the Common Lisp type system. But I'm trying to better understand the class relationships at the top of the hierarchy. For a simple example, let (defstruct person name age)
, and then (defparameter *p1* (make-person :name "Yosh" :age 19)
. Now
(typep *p1* 'person)
T
(typep *p1* 'structure)
T
(typep *p1* 'structure-object)
T
(typep *p1* 'atom)
T
(typep *p1* t)
T
The Hyperspec says the precedence list for structure-object
is only itself and t
.
Are atom
and structure
not types in the hierarchy?
What are all the direct subtypes of t
? More generally, how can you retrieve all the direct subtypes or supertypes of any given type (without trial-and-error subtypep
)? Alternately, is there a way to iterate over a list of all types? Does the MOP offer functions to get at all sub-/super-classes?
By analogy with set theory, it would seem that all Common Lisp types/classes could theoretically be subdivided into two subclasses of t
; namely, standard-object
(corresponding to elements with instances like the number 3, the string "abc", the structure s1, the method m1, etc.), and standard-class
(corresponding to sets with instances like the class standard-object
, the class number
, the class structure-object
, etc.). If this is not the actual subdivision of t
, does the reason have something to do with practical implementation; for example, avoiding recursive class relationships in the hierarchy?
Types and classes are two different things.
Don't confuse them.
Some types have corresponding classes. Most have not.
atom
is the name of a type, but not of a class.
CL-USER 18 > (find-class 'atom nil)
NIL
Since atom
is not a class, it can't be in any class precedence list.
Thus atom
is not in the class precedence list of structure-object
.
The type structure
is non-standard and not defined by ANSI CL.
Types are not in a class precedence list, classes are.
The interface for types:
DEFTYPE
TYPEP
SUBTYPEP
TYPE-OF
That's basically all you can do with types.
CLOS classes have corresponding types
CLOS functions and class precedence lists don't work with types, but classes have corresponding types.
CL-USER 23 > (defclass bar () ())
#<STANDARD-CLASS BAR 40200A2413>
CL-USER 24 > (typep (make-instance 'bar) 'bar)
T
CL-USER 25 > (type-of (make-instance 'bar))
BAR
CL-USER 26 > (class-of (make-instance 'bar))
#<STANDARD-CLASS BAR 40200A2413>
CLOS works with classes. Thus in an extended CLOS you can ask for subclasses and superclasses. But not for subtypes or supertypes.
History: Types and CLOS
Common Lisp started in CLtL1 with types and no CLOS.
CLOS and CLOS classes have been added years later. They have been added in such a way that some types got corresponding classes and such that classes have corresponding types.
Common Lisp allows to define types using type specifiers like AND
, OR
, SATISFIES
, MEMBER
, NOT
, ... For those no corresponding CLOS classes exist.
There are also compound type specifiers like (integer 0 100)
. There are also no corresponding CLOS classes for those types.
CL-USER 31 > (deftype integer100 () '(integer 0 100))
INTEGER100
CL-USER 32 > (find-class 'integer100)
Error: INTEGER100 is not the name of a class