重新定义打印对象方法以简化操作在不同的CL实现中具有不同的效果 [英] Redefinition of the print-object method for conses has different effects in different CL implementations

查看:51
本文介绍了重新定义打印对象方法以简化操作在不同的CL实现中具有不同的效果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

尝试以标准列表表示法打印conses,但始终以点对的形式打印,以最小的努力,我以这种方式重新定义了 print-object 方法:

Trying to print conses not in standard list notation, but always as dotted pairs, with the minimum effort, I have redefined the method print-object in this way:

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

但效果因不同的实现而异.

but the effect is different for different implementations.

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

In Clozure CL and in LispWorks Personal the result is what I was expecting:

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)))

在SBCL和AllegroCLexpress中,列表的打印方式没有变化:

while in SBCL and AllegroCLexpress nothing change in the way lists are printed:

* (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)

所以,我想知道这是否是由于语言规范中的某些歧义,是否将这种行为明确声明为未指定,是否是由于REPL与软件包之间的某种相互作用,或者最终是因为关于此定义,有一些实现是正确的,而有一些是不正确的.最后要注意的是,在SLIME中给出这样的定义会导致SLIME本身彻底崩溃!

So, I am wondering if this is due to some ambiguity in the specification of the language, if such behaviour is explicitly declared as unspecified, if this is due to some interaction of the REPL with the packages, or, finally, if there are implementations that are correct with respect to this definition and others which are incorrect. As final note, giving such definition inside SLIME causes total havoc of SLIME itself!

有人可以阐明这种差异,并提出一种替代方法(如果存在的话)来实现我的目标的问题较少?

Can somebody shed some light over such differencies, and also suggest an alternative way, if it exists, less problematic, of obtaining my objective?

推荐答案

CLHS11.1.2.1.2 列出了更改通用lisp包中的内容的约束-这似乎与情况19冲突.

CLHS 11.1.2.1.2 lists constraints on changing things in the common lisp package -- this seems to run afoul of situation 19.

除非明确允许,否则后果是不确定的以下操作是在操作符的外部符号上执行的COMMON-LISP软件包:

Except where explicitly allowed, the consequences are undefined if any of the following actions are performed on an external symbol of the COMMON-LISP package:

...

  1. 定义一种标准化通用函数的方法,该方法适用于所有自变量均为的直接实例的情况.标准化的课程.

仅当 * print-pretty * 为非零时,部分解决方法是使用

A partial workaround, just for when *print-pretty* is non-nil, would be to use a pretty print dispatch table.

;(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)

这篇关于重新定义打印对象方法以简化操作在不同的CL实现中具有不同的效果的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆