阅读这个问题使我思考什么是表达式的有效car。显然,符号和lambda可以使用通常的语法“调用”。根据超石化的说法
函数名n.1.(在环境中)一个符号或一个列表(setf符号),它是该环境中函数的名称。2.文号或名单(setf文号)。
因此,从理论上讲,(setf some-name)是一个函数名。我决定试一下。
(defun (setf try-this) ()
(format t "Don't name your functions like this, kids :)"))
((setf try-this))
(funcall '(setf try-this))
(setf (try-this))GNU CLISP、SBCL和ABCL都允许我定义这个函数。但是,SBCL和ABCL不允许我使用代码片段中显示的任何语法来调用它。另一方面,CLISP将运行前两个,但仍然在第三个错误。
我很好奇哪个编译器运行正确。由于SBCL和ABCL同意,我会猜测正确的实现应该拒绝该代码。作为第二个问题,我将如何从代码片段中调用我设计得难以置信的、无用的函数,因为我前面尝试过的功能不能移植地工作。或者,也许更有用,
发布于 2018-06-30 00:25:47
SETF函数必须至少使用一个参数,这是要存储在其中的新值。它也可以使用额外的参数,这些参数将从调用SETF的place表达式中的参数中填充。
当您使用SETF时,它必须有偶数的参数:您要分配给的每个位置都需要分配一个值。
所以应该是:
(defun (setf try-this) (new-value)
(format t "You tried to store ~S~%" new-value))
(setf (try-this) 3)
(funcall #'(setf try-this) 'foo)你不能用
((setf try-this) 'bar)因为窗体的car不包含函数名。它只能是符号或lambda表达式(尽管实现可以允许其他格式作为扩展)。
https://stackoverflow.com/questions/51110694
复制相似问题