Greg Pfeil的Class Hierarchy图提供了Common Lisp类型系统的全面图景。但我试图更好地理解层次结构顶部的阶级关系。对于一个简单的示例,让(defstruct person name age)
,然后(defparameter *p1* (make-person :name "Yosh" :age 19)
。现在
(typep *p1* 'person)
T
(typep *p1* 'structure)
T
(typep *p1* 'structure-object)
T
(typep *p1* 'atom)
T
(typep *p1* t)
T
Hyperspec表示,
structure-object
的优先级列表只有它自己和t
。atom
和structure
不是层次结构中的类型吗?t
的所有直接亚型是什么?更一般地说,如何检索任何给定类型的所有直接子类型或超类型(无需试错subtypep
)?或者,有没有办法循环访问所有类型的列表?MOP是否提供获得所有子/超级类的功能?通过类比集合论,似乎所有Common Lisp类型/类在理论上都可以细分为
t
的两个子类;即standard-object
(对应于具有数字3,字符串"abc",结构s1,方法m1等实例的元素)和standard-class
(对应于具有类standard-object
等实例的集合, 类number
,类structure-object
等)。如果这不是t
的实际细分,原因是否与实际实施有关;例如,避免层次结构中的递归类关系?
类型和类是两个不同的东西。
不要混淆它们。
某些类型具有相应的类。大多数没有。
atom
是类型的名称,但不是类的名称。
CL-USER 18 > (find-class 'atom nil)
NIL
由于atom
不是类,因此它不能位于任何类优先级列表中。 因此atom
不在structure-object
的类优先级列表中。
类型structure
是非标准的,不是由 ANSI CL 定义的。
类型不在类优先级列表中,类在
。类型的接口:
- 创建类型 ->
DEFTYPE
- 是一种类型吗? ->
TYPEP
- 一个类型是另一个类型的子类型吗? ->
SUBTYPEP
- 什么是某物的类型?->
TYPE-OF
这基本上是你可以对类型做的所有事情。
CLOS 类具有相应的类型
CLOS 函数和类优先级列表不适用于类型,但类具有相应的类型。
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 适用于类。因此,在扩展的 CLOS 中,您可以请求子类和超类。但不适用于亚型或超型。
历史记录:类型和 CLOS
Common Lisp 始于 CLtL1,有类型,没有 CLOS。
CLOS 和 CLOS 类是在几年后添加的。它们的添加方式是,某些类型具有相应的类,并且类具有相应的类型。
Common Lisp允许使用类型说明符定义类型,如AND
,OR
,SATISFIES
,MEMBER
,NOT
,... 对于这些,不存在相应的 CLOS 类。
还有复合类型说明符,如(integer 0 100)
.这些类型也没有相应的 CLOS 类。
CL-USER 31 > (deftype integer100 () '(integer 0 100))
INTEGER100
CL-USER 32 > (find-class 'integer100)
Error: INTEGER100 is not the name of a class
所有类都是类型,但并非所有类型都是类。某些类型是根据其他类型定义的。原子是任何不是缺点的东西。 由于结构的实例不是缺点,它是一个原子。 从超规格:
原子型
超类型:
原子,T
描述:
相当于
(not cons)
。
作为另一个常见示例,请考虑类型列表,它等效于(或 null cons)。NIL(类型为空)是一个列表,缺点是一个列表。 就是这样。
原子和列表都不是类,但它们是类型。
因为我们可以有补码类型、联合类型和交集类型,所以类型层次结构的概念变得有点复杂,即使仍然有适当的类层次结构。
Hyperspec说结构对象的优先级列表只是 本身和t。原子和结构不是层次结构中的类型吗?
这不是HyperSpec所说的。 HyperSpec说t是结构类型的超类型。 在 Common Lisp 中,您可以定义任意的新类型。 例如,对于一个简单的(deftype my-new-type(或结构对象列表)),你也会(typep *p1* 'my-new-type)返回true。 这不会突然使HyperSpec关于结构对象的类优先级的说法无效。
通过与集合论的类比,似乎所有Common Lisp类型/类在理论上都可以细分为t
这将是这样做的一种方式,但是由于能够根据类型并集、类型交集和类型补集来定义新类型,因此您可以通过多种方式按类型划分 Common Lisp 的对象。