In the post at Common Lisp class hierarchy, Rainer Joswig & Joshua Taylor carefully distinguish some of the differences between built-in Common Lisp types and classes, where classes form part of the CLOS extension to the baseline. The type/class (plus mop) distinctions are also reflected in Pfeil's comprehensive hierarchy diagram. Using the diagram, it seems possible to extract the two distinct hierarchies. In particular, I am currently most interested in the tops of the hierarchies; namely, the direct subtypes and subclasses of t
(since t
is both a type and a class). Here are some provisional subtypes/subclasses distilled from the diagram:
For the type hierarchy, the direct subtypes of t
seem to be atom
, character
, random-state
, hash-table
, restart
, readtable
, package
, pathname
, stream
, function
, array
, sequence
, number
, and condition
. All other types like float
or list
are subtypes of one of these types. The type hierarchy is also not strictly hierarchical (since (subtype t t) => T
, but this seems to be the only exception). (ps: the types symbol
and structure-object
are not included in the diagram, but also may be direct subtypes of t
.)
For the class hierarchy, the direct subclasses of t
include corresponding classes for all the types above (except atom
, and perhaps structure-object
which is now a subclass of standard-object
(?)), plus standard-object
.
The MOP extends CLOS by adding the class metaobject
(plus some meta-subclasses), but does not seem to add to the direct subclasses of t
.
Can someone verify if this understanding is correct, or provide additional clarifications?
Note: I've discovered at least one mistake in the type hierarchy description above. All of the listed subtypes (character
, etc.) are apparently subtypes of atom
, so they are not direct subtypes of t
. The only other direct subtype of t
seems to be sequence
, since a sequence can be a cons
(non-atom). Moreover, symbol
is, in fact, included in the diagram, and is also a subtype of atom
.
You already know that there are types and there are classes in Common Lisp.
Types categorize objects, while classes tag objects. Moreover, an object may be of many types, but it's a direct instance of a single class.
If you ask an object for its type through
type-of
, you may get many valid answers. A non-exhaustive example:For
typep
andsubtypep
, things are a lot more confusing, as you can generate types at will, like(eql 1)
,(member 1)
,(or fixnum bignum)
,(and (integer * 1) (integer 1 *))
,(not (satisfies zerop))
,(satisfies oddp)
, etc. for true results, and likewise for false results.However, for each object, you have exactly one class:
In practice, you can't determine the whole type hierarchy. There is the notion that anything is
t
, nothing isnil
and there might be an hierarchy for atomic standard types. But the reality is that there are compound types and user-defined types, so it's technically impossible to draw a full type hierarchy, as that would require to look at the result ofsubtypep
for every imaginable object.Even so, there might not exist a hierarchy between types. Taking the mistake you say you found, I believe the author did not want to litter the diagram with arrows pointing to
atom
for every type other thancons
. But in fact, that would probably not be a correct representation at all, since some objects of typelist
andsequence
arecons
and others areatom
, specifically, the empty list isatom
.However, you can determine the whole class hierarchy, even though a class may have multiple superclasses.
Some implementations return the
fixnum
class in theclass-of
example, an extension to the standard (fixnum
is a type but not a class), to allow CLOS method specialization onfixnum
and/or to allow optimization tricks.From a few implementations I tried, only CLISP returned the
integer
class.Graphing CL Subtypes of T in LispWorks:
Finding the subtypes:
Graphing it:
Graph
The types with corresponding CLOS classes are written in blue and structure classes are brown. The type
NIL
is not drawn. Included are types/classes from the CLOS MOP. Some types have more than one name. Also note that this graph is specific to LispWorks, especially what types are actually also structures, CLOS classes, built-in class or something else.The term direct subtype almost never makes sense.
Why do you think that
character
is a direct subtype oft
?But
character
is a subtype ofatom
which is a subtype oft
!Well, maybe
character
is a direct subtype ofatom
?Nope,
character
is a subtype of(or character number)
which is a subtype ofatom
.So, maybe
character
is a direct subtype of(or character number)
?Nope,
character
is a subtype of(or character integer)
which is a subtype of(or character number)
.You can think of classes as integers and types as rationals - there are no integers between 3 and 4, but there are plenty of rationals between any two different rationals.