我对lisp相当新,但我一直在玩它。我有几个问题需要澄清。下面是我定义的小宏。
(defmacro transform (query)
'(lambda (row)
(eq (nth 1 query) (nth 0 (nth 0 row)))
)
)
我只是想知道如何动态指定在身体中使用的功能?如果我想使用“+”或“ - ”函数而不是“eq”,或者甚至是我定义的另一个函数?就像我认为可以将函数的名称作为参数传递但显然不起作用。当我修改传入的列表(查询)时,我也会收到变量未绑定错误。
答案 0 :(得分: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))))))
此版本使用“反引号”而不是普通撇号,它允许在主体内“取消引用”表单,从而允许将生成的表单包含在结果中。
您可以像原始版本一样使用此宏:
(transform (...))
或(传递显式测试函数):
(transform (...) :test equal)
请注意,您不应在宏扩展中使用普通符号作为变量名称(作为生成的 lambda 表达式的行参数),因为这可能会意外干扰在使用宏的网站上使用该符号。您只是不知道何时编写宏,在使用宏时是否会在某处使用名为 row 的变量,以及它是否已在查询中使用形式/表达。您的原始定义将“捕获”变量,可能会改变查询所做的含义。
答案 1 :(得分:0)
funcall就是答案!决定只传入它并使用funcall来评估函数。