setf 函数名称
Setf function names
阅读 got me thinking about what constitutes a valid car of an expression. Obviously, symbols and lambdas can be "called" using the usual syntax. According to the hyperspec,
function name n. 1. (in an environment) A symbol or a list (setf symbol) that is the name of a function in that environment. 2. A symbol or a list (setf symbol).
所以,理论上,(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 一致,我会冒险猜测正确的实现应该拒绝该代码。作为第二个问题,我如何从代码片段中调用我难以置信的人为设计的无用函数,因为我在上面尝试的事情无法移植。或者,也许更有用,
一个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 表达式(尽管实现可能允许其他格式作为扩展)。
阅读
function name n. 1. (in an environment) A symbol or a list (setf symbol) that is the name of a function in that environment. 2. A symbol or a list (setf symbol).
所以,理论上,(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 一致,我会冒险猜测正确的实现应该拒绝该代码。作为第二个问题,我如何从代码片段中调用我难以置信的人为设计的无用函数,因为我在上面尝试的事情无法移植。或者,也许更有用,
一个SETF
函数至少要有一个参数,就是要存储在这个地方的新值。它也可以接受额外的参数,这些参数将在 SETF
.
当您使用 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 表达式(尽管实现可能允许其他格式作为扩展)。