gpt4 book ai didi

lisp - 来自 On Lisp 的奇异引用列表示例

转载 作者:太空宇宙 更新时间:2023-11-03 18:34:29 26 4
gpt4 key购买 nike

这段来自 On Lisp 的文章确实令人困惑——不清楚返回一个引用列表如 '(oh my) 是如何改变函数的行为的在 future :是否会在函数中从头开始重新生成返回列表,下次调用它时?

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

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

Then any later destructive modification of the return value

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

最后一次调用 exclaim 是如何将单词 goodness 添加到结果中的?该函数未引用任何外部变量,那么对 nconc 的单独调用实际上如何改变 exclaim 函数的工作方式?

最佳答案

a) Common Lisp 标准中未定义修改文字 列表的效果。您在此处看到的示例是一种可能的行为。

(1 2 3 4) 是一个文字列表。但是像 (list 1 2 3 4) 那样调用 LIST 会在运行时返回一个新的 consed 列表。

b) 列表是函数代码中的文字数据。每次调用都将准确返回此数据对象。如果您想在每次调用时提供新列表,则需要使用 LIST 或 COPY-LIST 之类的东西。

c) 由于返回的列表始终是相同的文字数据对象,因此修改它可以产生所描述的这种效果。还可以想象,如果代码及其对象分配在只读内存中,则会发生错误。然后修改列表将尝试写入只读内存。

d) 在源代码中处理文字列表数据时要记住的一件事是:Lisp 编译器可以自由优化存储。如果一个列表恰好在源代码中多次出现,则允许编译器检测到这一点并只创建一个列表。然后所有不同的地方都会指向这个列表。因此,修改列表会产生这样的效果,即这些更改可能会在多个地方可见。

这也可能发生在其他文字数据对象上,例如数组/向量。

如果你的数据结构是代码的一部分,你返回这个内部数据结构,你修改这个数据结构 - 然后你尝试修改你的代码。

另请注意,Lisp 可以由解释器执行。解释器通常在 Lisp 源代码结构上工作——代码不是机器代码,而是将 Lisp 代码解释为 Lisp 数据。在这里,您可以在运行时修改源代码,而不仅仅是源代码中嵌入的数据。

关于lisp - 来自 On Lisp 的奇异引用列表示例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23002279/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com