我的工作我的方式通过格雷厄姆的书籍"对口齿不清"并不能了解以下例在第37页:

If we define exclaim so that its return value
incorporates a quoted list,

(defun exclaim (expression)
  (append expression ’(oh my)))

>  (exclaim ’(lions and tigers and bears))
(LIONS AND TIGERS AND BEARS OH MY)
> (nconc * ’(goodness))
(LIONS AND TIGERS AND BEARS OH MY GOODNESS)

could alter the list within the function:

> (exclaim ’(fixnums and bignums and floats))
(FIXNUMS AND BIGNUMS AND FLOATS OH MY GOODNESS)

To make exclaim proof against such problems, it should be written:
(defun exclaim (expression)
  (append expression (list ’oh ’my)))

任何人都不会明白什么会在这里?这是真的搞砸了我的心理模型是什么引用。

有帮助吗?

解决方案

nconc是一种破坏性的操作,改变其通过改变其尾部的第一个参数。在这种情况下,这意味着恒定的列表'(oh my)得到一个新的尾部。

要希望使这个清晰。这有点像这样:

; Hidden variable inside exclaim
oh_my = oh → my → nil

(exclaim '(lions and tigers and bears)) =
    lions → and → tigers → and → bears → oh_my

(nconc * '(goodness)) destructively appends goodness to the last result:
    lions → and → tigers → and → bears → oh → my → goodness → nil
so now, oh_my = oh → my → goodness → nil

'(oh my)修复更换(list 'oh 'my)这一点,因为不再有由所有杂被共享的常数。到exclaim每次调用生成一个新的列表(list功能在生活中的目的是为了创造全新的列表)。

其他提示

这是你引用的心智模型可能存在缺陷的观察是一个很好的一个,尽管它可能还是取决于心智模式是什么可能不适用。

首先,请记住,有各种阶段的程序执行。甲Lisp的环境必须首先的程序文本到数据结构(列表,符号和各种文字数据诸如字符串和数字)。接着,它可以或不可以的编译这些数据结构成机器代码或某种中间格式的。最后,将得到的代码是的评估的(在机码的情况下,当然,这可简单地平均跳跃到相应的地址)。

让我们把编译的问题放在一边,并专注于阅读和评估阶段,假定(为了简化),该评估的输入结构读取读取器数据的列表。

考虑一个形式(QUOTE x)其中 X 是一个对象的某些文本表示。这可能是符号文字作为(QUOTE ABC),列表文字作为(QUOTE (A B C)),一个字符串作为(QUOTE "abc"),或任何其他形式的文字。在读取阶段,读取器将读取形式为列表(称之为 Form1中),其第一个元素是符号QUOTE并且其第二元件是对象的 X'其文本表示为 X 。请注意,我具体说,对象的 X'被存储的代表该表达式列表中下,即,在某种意义上说,它存储为的一个的一部分代码本身

现在它是评估的转变。评价者的输入是 Form1中,这是一个列表。因此,看起来在所述第一元件的 Form1中,和,已经确定它是符号QUOTE,的它返回作为评价的结果的列表的第二元件。这是至关重要的一点。评价者返回列表的第二个元素进行评估,这是读者在第一执行阶段读取(在编译之前!)。 这就是它。没有什么神奇的吧,这是非常简单的,和显著,没有创建新的对象,并没有现有的复制。

因此,当你修改“援引名单”,正在修改的代码本身。自修改代码是一个非常令人困惑的事情,并且在这种情况下,该行为实际上是未定义的(因为ANSI Common Lisp的允许实现把代码只读存储器)。

当然,以上所述仅仅是一个心理模型。实现可以自由地实现各种方式的模型,而事实上,我知道没有实现的Common Lisp的,像我的解释,确实没有编译可言的。尽管如此,这是基本的想法。

在公共口齿不清。

请记住:

'(1 2 3 4)

上面是一个 文字的列表. 恒定的数据.

(list 1 2 3 4)

列表是一个功能,时返回一个电话 新的名单 与其参数为列表中的要素。

避免修改文字的名单。该效应不是标准化。想象一下,一个口齿不清,汇编所有恒定的数据变成一个只写存储器区。想象一下,一个口齿不清,需要不断列出并分享他们在整个职能。

(defun a () '(1 2 3)

(defun b () '(1 2 3))

一个口齿不清的编译可以创建一个名单,是共享通过这两种功能。

如果你修改的列表返回的功能

  • 它可能不会改变
  • 它可能会被改变
  • 它可能是一个错误
  • 它还可能改变清单返回的功能b

实现自由做他们喜欢什么。这个留有优化。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top