我想知道这是如何工作:可以lisp函数返回引用或通过引用接收参数?
(SETF(车X)42)
不(车X)返回一个分配的参考SETF?或者这只是宏观魔法? setf或汽车如何工作?
我知道按引用传递在函数式编程中是一个可怕的罪,但我想知道上面是如何完成的。
我想知道这是如何工作:可以lisp函数返回引用或通过引用接收参数?
(SETF(车X)42)
不(车X)返回一个分配的参考SETF?或者这只是宏观魔法? setf或汽车如何工作?
我知道按引用传递在函数式编程中是一个可怕的罪,但我想知道上面是如何完成的。
这是宏观魔法。表单(setf的地方值)不过是一个专门的宏观扩展。例如,(setf(car x)42)将被翻译成如下形式:(rplaca x 42)。
你可以看到你的Lisp实现是如何扩展使用MACROEXPAND一个SETF形式,像这样(我的例子是使用SBCL,其他实施方式可以有完全不同的扩展):
CL-USER> (macroexpand '(setf (aref foo 10) 1234))
(SB-KERNEL:%ASET FOO 10 1234)
T
您也可以定义自己的扩展:
CL-USER> (defvar *value* 0)
*VALUE*
CL-USER> (defun get-value() *value*)
GET-VALUE
CL-USER> (defun (setf get-value) (x) (setq *value* x))
(SETF GET-VALUE)
CL-USER> (setf (get-value) 42)
42
CL-USER> (get-value)
42
CL-USER> (macroexpand '(setf (get-value) 23))
(LET*()
(MULTIPLE-VALUE-BIND (#:NEW1058) 23 (FUNCALL #'(SETF GET-VALUE) #:NEW1058)))
T
In Common Lisp,这是一个的地方。一个地方是一个定义了setf扩展器的表单。这就像一个广义的参考。请致电Hyperspec。