小编典典

Common Lisp中的`set`,`setq`和`setf`之间的区别?

all

Common Lisp 中的“set”、“setq”和“setf”有什么区别?


阅读 123

收藏
2022-07-17

共1个答案

小编典典

最初,在 Lisp 中,没有词法变量——只有动态变量。而且没有 SETQ 或 SETF,只有 SET 函数。

现在写成:

(setf (symbol-value '*foo*) 42)

写成:

(set (quote *foo*) 42)

最终缩写为 SETQ (SET Quoted):

(setq *foo* 42)

然后出现了词法变量,并且 SETQ 也开始用于对它们进行赋值——因此它不再是 SET 的简单包装器。

后来,有人发明了 SETF(SET Field),作为一种为数据结构赋值的通用方式,以反映其他语言的左值:

x.car := 42;

将被写为

(setf (car x) 42)

为了对称性和通用性,SETF 还提供了 SETQ 的功能。在这一点上,说 SETQ 是低级原语,而 SETF 是高级操作是正确的。

然后发生了符号宏。因此,符号宏可以透明地工作,如果分配给的“变量”实际上是符号宏,则 SETQ 必须像 SETF 一样工作:

(defvar *hidden* (cons 42 42))
(define-symbol-macro foo (car *hidden*))

foo => 42

(setq foo 13)

foo => 13

*hidden* => (13 . 42)

所以我们来到了今天:SET 和 SETQ 是旧方言的萎缩残骸,很可能会从 Common Lisp 的最终继承者中被淘汰。

2022-07-17