LISP 的功能语言家族和一个代码片段?

Functional Language Family of LISP and one Code Fragment?

在 LISP 的一个功能语言家族中并且可以定义变量,

(defvar a '(1 2 3))
(defvar b (cons a (cdr a)))
(rplacd a '(5))

b 列表创建为

((1 5) 2 3)

!!我很惊讶。这些代码片段是如何构成这个列表的?谁能解释一下这些令人困惑的命令?!

执行前两个 defvar 调用后,您可以为 conses 分配以下变量。

A => +---+---+  +---+---+  +---+---+      
+--> | 1 | ---->| 2   ---->| 3 | ----> NIL
 \   +---+---+  +---+---+  +---+---+
  \            --^
   \          /   
    \        /                        
     \      /                        
      \    /      
B => +-\-+-|-+    
     | | | | |    
     +---+---+

在印刷表示中,这看起来像:

A => (1 2 3)
B => ((1 2 3) 2 3)

当您执行 rplacd 时,它会修改 acdr 以引用新的 cons。但是 bcdr 仍然引用与之前相同的 cons

               +---+---+
             ->| 5 | ----> NIL
            /  +---+---+     
           /
A => +---+-|-+  +---+---+  +---+---+      
+--> | 1 | | |  | 2   ---->| 3 | ----> NIL
 \   +---+---+  +---+---+  +---+---+
  \            --^
   \          /   
    \        /                        
     \      /                        
      \    /      
B => +-\-+-|-+    
     | | | | |    
     +---+---+

印刷形式如下:

A => (1 5)
B => ((1 5) 2 3)

了解 Lisp 赋值的重要一点是它们不复制列表结构,它们只是分配对 conses 的引用(如果您熟悉像 C 这样的语言,就好像一切都是指针struct).