Common lisp 在不同的CL实现中,CONSE的打印对象方法的重新定义具有不同的效果

Common lisp 在不同的CL实现中,CONSE的打印对象方法的重新定义具有不同的效果,common-lisp,sbcl,clos,ansi-common-lisp,Common Lisp,Sbcl,Clos,Ansi Common Lisp,尝试以非标准列表表示法打印conses,但总是以虚线对的形式打印,我已以这种方式重新定义了方法print object: (defmethod print-object((c cons) str) (format str "(~a . ~a)" (car c) (cdr c))) 但是,对于不同的实现,效果是不同的 在Clozure CL和LispWorks Personal中,结果是我所期望的: CL-USER 1 > (defmethod print-object((c cons

尝试以非标准列表表示法打印conses,但总是以虚线对的形式打印,我已以这种方式重新定义了方法
print object

(defmethod print-object((c cons) str)
  (format str "(~a . ~a)" (car c) (cdr c)))
但是,对于不同的实现,效果是不同的

在Clozure CL和LispWorks Personal中,结果是我所期望的:

CL-USER 1 > (defmethod print-object((c cons) str)
                (format str "(~a . ~a)" (car c) (cdr c)))
#<STANDARD-METHOD PRINT-OBJECT NIL (CONS . (T . NIL)) 200A45AB>

CL-USER 2 > '(a b c )
(A . (B . (C . NIL)))
CL-USER 1>(defmethod打印对象((c cons)str)
(格式str“(~a.~a)”(car c)(cdr c)))
#
CL-USER 2>'(a b c)
(A.(B.(C.无)))
在SBCL和AllegroCLexpress中,列表的打印方式没有任何变化:

* (defmethod print-object((c cons) str)
     (format str "(~a . ~a)" (car c) (cdr c)))

#<STANDARD-METHOD PRINT-OBJECT (CONS T) {10051EBC53}>
* '(a b c)

(A B C)
*(defmethod打印对象((c cons)str)
(格式str“(~a.~a)”(car c)(cdr c)))
#
*"(甲,乙,丙)
(A、B、C)
因此,我想知道这是否是由于语言规范中的一些模糊性造成的,如果这种行为被明确声明为未指定,如果这是由于REPL与包之间的一些交互,或者,最后,是否有关于此定义的正确实现和其他不正确的实现。最后一点,在粘液中给出这样的定义会导致粘液本身的彻底破坏


有人能解释一下这种差异吗?如果存在的话,也能提出一种不那么麻烦的替代方法来实现我的目标吗?

这个标题有点误导。SBCL没有用于CONSE的
打印对象
方法。所以你不能重新定义它。出于某种原因,它允许您定义这样的方法,但它的打印机不会调用它

另外,SBCL不支持内置类型上的用户定义的
打印对象
方法。打印机不会调用它们。如果查看打印机源,它使用的是
TYPE-CASE
构造,为不同的数据类型调用各种打印函数

您可以为SBCL中的CLOS类定义
print object
方法,并将调用这些方法

这与ANSI CL不兼容吗?大概至少不提供
打印对象
方法的部分应该是不兼容的。这仍然不意味着可以改变它们

根据
PRINT-OBJECT
方法定义所有/大多数/许多类(包括内置类)的打印是否有用。是的。

列出了在公共lisp包中更改内容的约束条件——这似乎与第19种情况背道而驰

除非明确允许,否则后果未定义(如有) 对的外部符号执行以下操作之一: COMMON-LISP软件包:

  • 定义标准化泛型函数的方法,当所有参数都是 标准化班级
  • 仅当
    *print pretty*
    为非零时,部分解决方法是使用


    我同意你的最后一句话,因为在CL中,你可以重新定义很多东西,包括几乎所有关于阅读的东西,而改变写作的基本方面是不可能的。我认为关于不兼容性的答案应该是肯定的,因为CLHS 22.1.3以“本节描述了标准化类型的打印对象(链接到打印对象)方法的默认行为”开头。因此,在我看来,标准要求标准化类型的值应使用PRINT-OBJECT实例打印(另一个答案的第19点适用)。感谢您在手册中指出了正确的点,并提供了解决方法!
    ;(in-package cl-user)
    (set-pprint-dispatch 'cons (lambda (s obj) (format s "(~A . ~A)" (car obj) (cdr obj))))
    NIL
    ;(in-package cl-user)
    (let ((*print-pretty* t)) (print (list 1 2 3)))
    
    (1 . (2 . (3 . NIL)))
    (1 2 3)
    ;(in-package cl-user)