Lisp编程风格:setq vs. setf

25

彼得·诺维格在《人工智能编程范式》(Paradigms of Artificial Intelligence Programming)中提到,在选择使用setq或setf将变量更新为一个值时,特定性和一致性之间存在权衡。你有什么建议?你是否遇到过除了可读性以外的重要情况?page 50

6个回答

20
使用setq更低级别,但setf的性能不是问题。而且setf允许您(或库编写者)提供自定义的setf行为,例如设置自定义数据结构的部分。我建议:除非有理由不使用,否则到处都用setf。
另请参见《实用Common Lisp》第3章:“SETF宏是Common Lisp的主要赋值运算符。” PCL可以免费在线获取:http://gigamonkeys.com/book/

12

顺便说一下,我总是使用setf。如果我稍微更改了代码的结构,我只需要更改“位置”而不是位置和操作符(setq-> setf)。

另外,不用担心性能问题,对于符号而言,setf与setq完全相同:

CL-USER> (macroexpand '(setf foo 42))
(SETQ FOO 42)

11

您可以在任何使用setq的地方使用setf。实际上,setf是一个基于setq构建的宏。因此,这应该纯粹是可读性和样式问题。

我看到的几乎所有代码都避免使用setq,而使用setf


4

setf 是 "set field" 的缩写,它可以更改一个 位置 并且可以具有用户扩展功能。setq 使用引用第一个参数进行设置。


1
我建议你遵循 Norvig 在该部分的最终建议:保持一致。 “可读性”当然是做出任何编程选择的最重要原因。 如果重要的是向读者(可能是两个月后的你)传达你正在处理符号的整个值单元格,那么请使用setq;否则请使用setf。 但只有在保持一致的情况下才这样做。

-2

如果你在所有地方都使用setf而不是setq,那么你不会错。

正是这样的事情阻碍了Common Lisp的前进,有很多未使用的东西需要实现者仍然需要支持。


3
我反对第二句话。SETF是对几个赋值构造的方便抽象,其中之一是SETQ。如果没有SETQ,你无法实现SETF。 - Svante
2Svante:但很难想象在什么情况下需要使用setq而不是setf。 - Anton Kazennikov
7
这不是重点 - 在高级代码中也没有人使用TAGBODY和GO,但许多常见结构的实现取决于它们。 - Svante

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接