common-lisp - Common Lisp 中 `set` 、 `setq` 和 `setf` 之间的区别?

标签 common-lisp

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

最佳答案

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

现在写成:

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

写为:

(set (quote *foo*) 42)

最终缩写为 SETQ(SET 引用):

(setq *foo* 42)

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

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

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 的最终继承者中被淘汰。

关于common-lisp - Common Lisp 中 `set` 、 `setq` 和 `setf` 之间的区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/869529/

相关文章:

emacs - SLIME 未从 Emacs 加载

lisp - List of List 麻烦 LISP

multithreading - SQLITE3 CLSQL多线程插入导致错误

Lisp 等级到字母的转换

common-lisp - 常见的 lisp 实现在运行时修改堆栈大小

lisp - 如何在 Common Lisp 中将列表打印为矩阵

stack-overflow - 使用 GNU CLIsp 获取堆栈溢出 (Windows)

Emacs SLIME - Common Lisp - 评估区域并打印所有结果

lisp - 什么是 Lisp 图像?

sql-server - 使用集成身份验证将 Windows 上的 SBCL 连接到 SQL Server