首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Common Lisp中`set`、`setq`和`setf`的区别?

Common Lisp中`set`、`setq`和`setf`的区别?
EN

Stack Overflow用户
提问于 2009-05-15 16:00:32
回答 5查看 96.2K关注 0票数 188

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

EN

回答 5

Stack Overflow用户

回答已采纳

发布于 2009-05-15 16:36:39

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

现在是这样写的:

代码语言:javascript
复制
(setf (symbol-value '*foo*) 42)

是这样写的:

代码语言:javascript
复制
(set (quote *foo*) 42)

最终缩写为SETQ (SET Quoted):

代码语言:javascript
复制
(setq *foo* 42)

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

后来,有人发明了SETF (设置字段),作为一种通用的赋值给数据结构的方法,以反映其他语言的l值:

代码语言:javascript
复制
x.car := 42;

将被写成

代码语言:javascript
复制
(setf (car x) 42)

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

然后发生了符号宏。为了使符号宏能够透明地工作,人们意识到,如果被赋值的“变量”真的是一个符号宏,那么SETQ必须像SETF一样工作:

代码语言:javascript
复制
(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的最终继任者那里启动。

票数 187
EN

Stack Overflow用户

发布于 2009-09-25 06:57:35

代码语言:javascript
复制
(set ls '(1 2 3 4)) => Error - ls has no value

(set 'ls '(1 2 3 4)) => OK

(setq ls '(1 2 3 4)) => OK - make ls to (quote ls) and then have the usual set

(setf ls '(1 2 3 4)) => OK - same as setq so far BUT

(setf (car ls) 10) => Makes ls '(10 2 3 4) - not duplicated by setq/set
票数 169
EN

Stack Overflow用户

发布于 2009-05-15 16:18:15

setq就像带引号的set -- (set 'foo '(bar baz))就像(setq foo '(bar baz))。另一方面,setf确实很微妙--它就像一个“间接的”。我建议http://www.n-a-n-o.com/lisp/cmucl-tutorials/LISP-tutorial-16.html作为一种更好的方式来开始理解它,而不是这里的任何答案。简而言之,setf将第一个参数作为“引用”,这样(aref myarray 3)就可以(作为setf的第一个arg )在数组中设置项。

票数 22
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/869529

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档