便携使用make-instance来制作条件?

Portable to use make-instance to make conditions?

在 Common Lisp 中,使用 make-instance 而不是 make-condition 来创建条件对象是否可移植?

例如:

(define-condition foo (condition)
  ())

(make-condition 'foo)
(make-instance 'foo)

这是否与条件在 CLOS class 层次结构中的放置方式有关? (subtypep 'condition 'standard-class) returns 在 SBCL 和 CLISP 中为假。但是,make-instance 可以在两种实现中都创建条件。这个有标准保证吗?

它不可移植,根据 Practical Common Lisp 第 19 章第 4 个脚注:

"在某些 Common Lisp 实现中,条件被定义为 STANDARD-OBJECT 的子类,在这种情况下,SLOT-VALUE、MAKE-INSTANCE 和 INITIALIZE-INSTANCE 将起作用,但它不可移植到靠它。"

Link 到特定页面:

http://www.gigamonkeys.com/book/beyond-exception-handling-conditions-and-restarts.html

不,这样做显然不可移植。来自 specification:

Conforming code must observe the following restrictions related to conditions:

  • define-condition, not defclass, must be used to define new condition types.
  • make-condition, not make-instance, must be used to create condition objects explicitly.
  • The :report option of define-condition, not defmethod for print-object, must be used to define a condition reporter.
  • slot-value, slot-boundp, slot-makunbound, and with-slots must not be used on condition objects. Instead, the appropriate accessor functions (defined by define-condition) should be used

您可以通过

检查某个实现中的条件系统是否正在使用CLOS并支持CLOS操作
(subtypep 'condition 'standard-class)

但也许可以使用类似的东西:

(subtypep (class-of (find-class 'condition)) 'standard-class)

Common Lisp 标准不要求实现使用 CLOS 来实现条件。因此,标准中的条件系统是在不支持 CLOS 的情况下定义的:不支持 make-instance 要求,不支持通过 defclass 创建子类,...因此也不能指望其他功能正在使用 CLOS。

这是 1994 年 Common Lisp 标准的缺点之一。