修改作为参数传递的列表在SBCL和CLISP中给出不同的结果

编程入门 行业动态 更新时间:2024-10-24 01:56:45
本文介绍了修改作为参数传递的列表在SBCL和CLISP中给出不同的结果的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

有人可以解释为什么我为以下带有sbcl和clisp的简单程序得到不同的结果吗?是我在用语言定义的工作是不确定的,还是两个口齿不清的解释器之一?

Can someone explain why I get different results for the following simple program with sbcl and clisp? Is what I am doing undefined by the language, or is one of the two lisp interpreters wrong?

; Modify the car of the passed-in list (defun modify (a) (setf (car a) 123)) ; Create a list and print car before and after calling modify (defun testit () (let ((a '(0))) (print (car a)) (modify a) (print (car a)))) (testit)

SBCL (版本1.0.51)产生:

SBCL (version 1.0.51) produces:

0 0

CLISP(版本2.49)产生(我期望):

CLISP (version 2.49) produces (what I would expect):

0 123

推荐答案

I同意Seth和Vsevolod的评论,因为此行为是由于您对文字数据的修改而引起的。尝试使用(列表0)代替’(0)。与此相关的问题相对频繁地出现,因此我将引用 HyperSpec 此处。

I agree with Seth's and Vsevolod's comments in that this behavior is due to your modification of literal data. Try using (list 0) instead of '(0). Questions relating to this come up relatively frequently, so I'll quote the HyperSpec here.

3.7.1文字对象的修改:

如果文字对象具有破坏性,则后果不明确

The consequences are undefined if literal objects are destructively modified.

文字的定义:

文字调整。直接在程序中而不是由程序计算的(对象的);也就是说,以的报价形式显示为数据,或者,如果该对象是自评估对象,则以的形式显示为未报价的数据。 以(cons one'( two)的形式,表达式 one,( two)和 two是文字对象。

literal adj. (of an object) referenced directly in a program rather than being computed by the program; that is, appearing as data in a quote form, or, if the object is a self-evaluating object, appearing as unquoted data. ``In the form (cons "one" '("two")), the expressions "one", ("two"), and "two" are literal objects.''

请注意,经常(在许多实现中)如果修改文字值,您实际上会在代码本身中对其进行修改–编写自修改代码。您的示例代码将无法正常工作。

Note that often (in many implementations), if you modify literal values, you'll really modify them in the code itself – writing self modifying code. Your example code will not work as you expect.

您在CCL中的示例代码:

Your example code in CCL:

CL-USER> (defun modify (a) (setf (car a) 123)) MODIFY CL-USER> (defun testit () (let ((a '(0))) (print (car a)) (modify a) (print (car a)))) TESTIT CL-USER> (testit) 0 123 123 CL-USER> (testit) 123 123 123

看一下 testit 的第二次评估,其中 let 本身实际上已经包含修改后的值,因此第一次 print 也会产生 123 。

Take a look at the second evaluation of testit, where the let itself really already contains the modified value, thus the first print also yields 123.

另请参见: Lisp,cons和(number.number)差异,其中我对此进行了更详细的解释,或者解释了上面Vsevolod的评论中链接的问题。

Also see: Lisp, cons and (number . number) difference, where I explained this in more detail, or the question linked in Vsevolod's comment above.

更多推荐

修改作为参数传递的列表在SBCL和CLISP中给出不同的结果

本文发布于:2023-07-31 15:41:38,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1260019.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:参数   列表   CLISP   SBCL

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!