lisp函数可以通过引用返回引用或接收参数吗?

sal*_*r p 4 lisp reference

我想知道这是如何工作的:

(setf(车x)42)

(car x)是否返回setf的可赋值引用?或者只是宏观魔术?setf或汽车如何工作?

我知道通过引用传递将是函数式编程中的一个可怕的错误,但我想知道上面是如何完成的.

Eli*_*son 9

这是宏观的魔力.表单(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
Run Code Online (Sandbox Code Playgroud)

您还可以定义自己的扩展:

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
Run Code Online (Sandbox Code Playgroud)


Sva*_*nte 6

在Common Lisp中,这是一个地方.地点是定义了setf扩展器的表单.它就像一个通用的参考.

如需深入治疗,请查看Hyperspec.