在Lisp中,如何从宏中调用名称为符号的符号值的函数?我可能错了,但我认为我是对的,符号是一个变量。
以下是我目前的情况:
(defmacro cfunc (a b) (list a b))
(defparameter foo 'my-func)
(defun my-func (data) '(some-code))
(cfunc foo data) ;does not work
(cfunc my-func data) ;works
我想我需要在foo
前面添加一些特殊字符,以便在被视为函数之前评估其符号值。 (cfunc foo data)
创建并调用函数(foo data)
而不是(my-func data)
。我想我可以改变cfunc
中定义的函数。
#'foo
不起作用,这会(function foo)
cfunc
返回并调用((function foo) data)
。 (symbol-value foo)
也无法正常工作。所以我想我无法改变cfunc
的内容,但我可以更改cfunc
函数的代码。
如果有人拥有某个资源的特定页面,该页面会告诉我使用defmacro
评估和扩展的内容,或者#
和'
等特殊字符的详细信息,或者知道关键字我应该如果可以共享,我会很感激。
答案 0 :(得分:2)
首先,在(cfunc foo data)
形式中,data
指的是什么?我在这里没有看到它的任何定义。它仅作为my-func
函数的参数偶然提到,它不会对cfunc
的扩展发挥作用。也许您希望data
稍后可以作为特殊变量使用。
无论如何,您遇到的问题是Common Lisp是一个" Lisp-2&#34 ;;存在于function form头部的变量不会自动访问其功能单元以将其强制转换为函数。在您的情况下,foo
不是环境中绑定的函数;它是一个变量,其值是一个符号(my-func
) - 一个又与一个函数绑定。要导航这个额外的间接级别,您必须通过funcall
或其他情况function
请求访问该符号的功能单元。
以下是REPL的一些观察结果:
> (symbol-value 'foo)
MY-FUNC
> (ignore-errors (symbol-function 'foo))
NIL
#<UNDEFINED-FUNCTION FOO {1004E22D23}>
> (fboundp 'foo)
NIL
> (ignore-errors (symbol-value 'my-func))
NIL
#<UNBOUND-VARIABLE MY-FUNC {1005324E93}>
> (symbol-function 'my-func)
#<FUNCTION MY-FUNC>
> (fboundp 'my-func)
T
我们在此处看到符号foo
具有值绑定 - 意味着它是变量 - 但它没有功能绑定。在foo
到my-func
之后,我们发现my-func
没有值绑定,但它确实有函数绑定。
要结束,您的cfunc
宏需要编写如下:
(defmacro cfunc (a b)
(list 'funcall a b))
或者,您可以这样写:
(defmacro cfunc (a b)
`(funcall ,a ,b))
你最初提到的是表格
(cfunc my-func data)
按预期工作。根据我上面提出的修订版,它不再工作了,因为现在my-func
被视为要作为funcall
的参数进行评估的值,实际上它没有值单元格(因为它是一个功能)。因此,您必须使表单适应以下内容:
(cfunc #'my-func data)
那句话,&#34;查找符号&#39; my-func&#39;在函数名称空间中,获取其值,并将该函数作为参数提供。&#34;
要更精确地处理Lisp-1和-2中处理此类符号指向函数的差异,请参阅Gabriel的Technical Issues of Separation in Function Cells and Value Cells - 特别是第5节,&#34 ;符号简洁&#34;。