在Lisp中,如何通过名称作为参数传递来调用宏中的函数?

时间:2014-10-10 18:40:22

标签: function variables lisp common-lisp

在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评估和扩展的内容,或者#'等特殊字符的详细信息,或者知道关键字我应该如果可以共享,我会很感激。

1 个答案:

答案 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具有值绑定 - 意味着它是变量 - 但它没有功能绑定。在foomy-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;。