3

我有一个关于 elisp 的问题。例如:

(setq trees '(maple oak pine birch))
      -> (maple oak pine birch)
(setcdr (nthcdr 2 trees) nil)
      -> nil
trees
      -> (maple oak pine)

我认为(nthcdr 2 trees)返回一个新列表 -(pine birch)并将列表放入setcdr表达式中,这不应该改变trees. 谁能给我解释一下?

4

3 回答 3

4

如果您阅读 的文档字符串nthcdr,您会发现它只是返回一个指向“nth”“cdr”的指针——它是指向原始列表的指针。因此,您正在修改原始列表。

文档字符串:

Take cdr N times on LIST, return the result.

编辑哇,“指针”似乎引起了混乱。是的,Lisp 有指针。

只需查看用于解释 lisp 中列表结构的方框图(这里是Emacs 的文档):

     --- ---      --- ---      --- ---
    |   |   |--> |   |   |--> |   |   |--> nil
     --- ---      --- ---      --- ---
      |            |            |
      |            |            |
       --> rose     --> violet   --> buttercup

看看所有这些箭头,它们几乎看起来像是在……指向东西。当您获取cdr列表时,您会得到第二个框所指的内容(也称为“指向”),无论是原子、字符串还是另一个 cons 单元格。哎呀,在维基百科的CAR 和 CDR条目中查看。

如果将其称为参考更好,请使用该术语。

cdr当然不会返回它所指内容的副本,这让RNAer感到困惑。

于 2013-02-06T06:35:17.597 回答
3

R:“看,在天空中!拉姆达信号!一个公民有麻烦拉姆达人!”

LM:“我明白了!而且我有他们需要的盒子艺术。”


在 Lisps 中,列表是单链接的数据结构,由称为cons 单元的元素组成。这些细胞中的每一个都是一个结构,由

  1. 指向值的指针
  2. 指向下一个单元格的指针

由于历史原因,它们分别被称为carcdr 。这是代表 3 元素列表的传统盒子艺术:

Structure:    (car . cdr -)--->(car . cdr -)--->(car . cdr)
                |                |                |      |
                v                v                v      v
Values:         1                2                3     nil

car和函数允许您使用cdr这种低抽象级别的列表,并返回相应单元格的值。因此,car返回单元格的“值”,并cdr取消对列表其余部分的引用。nthcdrcdr为了方便起见的概括。

返回的值cdr是对原始数据结构的引用,该结构在此级别是可变的。如果你改变了一个 cons-cell 的 cdr 的值,你就改变了列表的底层结构。

鉴于:

 let A = '(1 2)    ~= (1 . -)-->(2 . nil)

 let B = '(3 4)    ~= (3 . -)-->(4 . nil)

将 cdr 设置(cdr A)为 B 将破坏性地连接 A 和 B 使得 A 现在是以下结构:

 A                   B     
 (1 . -)-->(2 . -)-->(3 . -)-->(4 . nil)

正如我们所展示的,nil一个单元格的 cdr 中的值代表列表的结尾——没有什么可以遍历的了。如果我们将 A 的 cdr 设置为nil,我们对列表进行 lobotomise,使得 A 现在

A                  
(1 . nil)  <- [Not pointing to anything - the rest of the list shall go wanting]

这几乎就是你所做的——你已经使用低级函数改变了底层数据结构。:) 通过将单元格的其中一个 cdrs 设置为nil,您已将列表的结尾剪掉了。

于 2013-02-06T10:25:42.067 回答
0

这被称为“突变”。除了 Haskell 之外,它无处不在。

有一些函数可以改变数据结构和复制它的函数。

于 2013-02-06T10:24:57.843 回答