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
时,它会修改 a
的 cdr
以引用新的 cons
。但是 b
的 cdr
仍然引用与之前相同的 cons
。
+---+---+
->| 5 | ----> NIL
/ +---+---+
/
A => +---+-|-+ +---+---+ +---+---+
+--> | 1 | | | | 2 ---->| 3 | ----> NIL
\ +---+---+ +---+---+ +---+---+
\ --^
\ /
\ /
\ /
\ /
B => +-\-+-|-+
| | | | |
+---+---+
印刷形式如下:
A => (1 5)
B => ((1 5) 2 3)
了解 Lisp 赋值的重要一点是它们不复制列表结构,它们只是分配对 conses 的引用(如果您熟悉像 C 这样的语言,就好像一切都是指针struct
).
在 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
时,它会修改 a
的 cdr
以引用新的 cons
。但是 b
的 cdr
仍然引用与之前相同的 cons
。
+---+---+
->| 5 | ----> NIL
/ +---+---+
/
A => +---+-|-+ +---+---+ +---+---+
+--> | 1 | | | | 2 ---->| 3 | ----> NIL
\ +---+---+ +---+---+ +---+---+
\ --^
\ /
\ /
\ /
\ /
B => +-\-+-|-+
| | | | |
+---+---+
印刷形式如下:
A => (1 5)
B => ((1 5) 2 3)
了解 Lisp 赋值的重要一点是它们不复制列表结构,它们只是分配对 conses 的引用(如果您熟悉像 C 这样的语言,就好像一切都是指针struct
).