Common Lisp中的"set“、"setq”和"setf“有什么区别?
发布于 2009-05-15 16:36:39
最初,在Lisp中,没有词法变量--只有动态变量。没有SETQ或SETF,只有SET函数。
现在是这样写的:
(setf (symbol-value '*foo*) 42)
是这样写的:
(set (quote *foo*) 42)
最终缩写为SETQ (SET Quoted):
(setq *foo* 42)
然后出现了词法变量,并且也开始使用SETQ对它们进行赋值--因此它不再是SET的简单包装器。
后来,有人发明了SETF (设置字段),作为一种通用的赋值给数据结构的方法,以反映其他语言的l值:
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的最终继任者那里启动。
发布于 2009-09-25 06:57:35
(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
发布于 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 )在数组中设置项。
https://stackoverflow.com/questions/869529
复制相似问题