通用Lisp类层次结构

3

Greg Pfeil的类层次结构图提供了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
  1. Hyperspec指出structure-object的优先级列表只有它本身和t。那么atomstructure不是层次结构中的类型吗?

  2. t的所有直接子类型是什么?更一般地说,如何检索任何给定类型的所有直接子类型或超类型(而不使用试错的subtypep)?或者,是否有一种方法可以迭代所有类型的列表?MOP是否提供了获取所有子/超类的函数?

  3. 类比于集合论,所有Common Lisp类型/类理论上都可以分为两个t的子类别;即standard-object(对应于具有实例的元素,例如数字3、字符串"abc"、结构s1、方法m1等),以及standard-class(对应于具有实例的集合,例如类standard-object、类number、类structure-object等)。如果这不是t的实际细分,原因是否与实际实现有关,例如避免层次结构中的递归类关系?

2个回答

8

类型和类是两个不同的概念。

不要混淆它们。

有些类型与相应的类对应,而大多数则没有。

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允许使用类型说明符定义类型,例如ANDORSATISFIESMEMBERNOT等。对于这些类型,不存在相应的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

既然所有类都有相应的类型,那么可以假设您只需使用 subtypep 来测试子类以及子类型吗?同样地,您可以使用 type-of 来发现任何对象(基本或 clos)的类型,而如果需要访问实际的类对象,则使用 class-of - davypough

2
所有的类都是类型,但并非所有的类型都是类。有些类型是基于其他类型定义的。原子(atom)是任何不是cons的东西。由于结构体的实例不是cons,它就是一个原子。来自HyperSpec的描述:

类型 ATOM

超类型:

atom,t

描述:

它等同于(not cons)

另一个常见的例子是考虑类型list,它等同于(or null cons)。NIL(类型为null)是一个列表,而cons也是一个列表。就是这样。

既不是atom也不是list是类,但它们都是类型。

因为我们可以有补集类型、联合类型和交集类型,所以即使仍然存在适当的类层次结构,类型层次结构的概念也变得更加复杂。

HyperSpec说结构对象的优先级列表只包括自身和t。原子和结构不是层次结构中的类型吗?

这并不完全是HyperSpec所说的。HyperSpec说t结构类型的超类型。在Common Lisp中,您可以定义任意新类型。例如,使用简单的(deftype my-new-type (or structure-object list)),您也可以使(typep *p1* 'my-new-type)返回true。这并不会突然使HyperSpec对于structure-object的类优先级无效。

类比集合论,所有Common Lisp类型/类似乎都可以理论上被划分为t的两个子类

这是一种做法,但由于可以通过类型的并集、交集和补集来定义新类型,因此有许多方法可以按类型对Common Lisp中的对象进行分区。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接