2009-09-01 74 views
0

我对lisp很新,但我一直在玩它。我有几个问题需要澄清。下面是我定义的小宏。如何根据传入的变量调用特定的函数?

(defmacro transform (query) 
'(lambda (row) 
    (eq (nth 1 query) (nth 0 (nth 0 row))) 
) 
) 

我只是想知道如何指定功能在体内动态使用?说如果我想使用“+”或“ - ”功能而不是“eq”,或者甚至是我定义的另一个功能?就像我认为可以将函数的名称作为参数传递,但显然不起作用。当我修改传入的列表(查询)时,我也会得到可变的未绑定错误。

+1

你有什么想法,为什么这应该是一个宏而不是一个函数? – 2009-09-01 11:43:02

+0

我已经将它改回到一个函数,它似乎工作正常。 – 2009-09-01 12:12:36

回答

0

funcall是答案!决定只是通过它并使用funcall来评估功能。

2

在宏的主体中,您可以使用Lisp的所有运行时库来生成实际的扩展。因此,例如:

(defmacro transform (query &key (test 'eq)) 
    (let ((row-var (gensym))) 
    `(lambda (,row-var) 
     (,test (nth 1 ,query) (nth 0 (nth 0 ,row-var)))))) 

这个版本使用“反引号”,而不是一个普通的撇号,这允许体内形式“unquoting”,从而允许夹杂物生成的表单到结果。

您可以使用此宏像你原来的版本:

(transform (...)) 

或(传递一个明确的测试功能):

(transform (...) :test equal) 

注意,你不应该用简单的符号来表示与变量名宏扩展(因为您的参数生成的lambda表达式),因为这可能会意外地干扰在使用您的macr时使用该符号O操作。你根本不知道什么时候写你的宏,是否会有一个变量叫做某处,当你的宏被使用时,以及它是否已经在查询表单/表达式中使用过。您的原始定义将“捕捉”变量,可能会改变任何查询的含义。

相关问题