【发布时间】:2017-11-25 09:54:18
【问题描述】:
我有一个宏:mac1(&rest args),它接受任意数量的参数
由于我不能将apply 与宏一起使用,并且由于我无法控制宏的实现,我如何才能使给定列表的函数fun1 (lst) 使用扩展列表调用宏?
更新:虽然我的问题已经足够了,但似乎最好陈述我的真实情况:
Postmodern 提供查询宏:
macro: query (query &rest args/format)
比如你这样称呼它:
(query
"select * from example where col1 = $1::integer and col2 = $2::date"
123
"2017-01-01"
:str-alists)
好的,现在想象一下,在运行时我通过了这个列表:
'((:query "select * from table1 where c1 = $1 and c2 = $2 and c3 = $3"
:params (1 "2017-01-01" 3) :return :str-alists
(:query "select * from tab2 where c3 = $1"
:params ("somevalue") :return :lists)
.
.
.
))
我必须进行查询。我需要定义一个将这样的列表作为参数并进行查询的函数。但是由于查询是一个宏,我有以下问题:我需要在某个地方评估列表,以便将它们传递给宏。目前我正在这样做(想法来自@melpomene cmets):
(defun macro-apply(q p ret)
(eval (macroexpand `(query ,q ,@p ,ret))))
所以函数变成:
(defun exec-queries (lst)
(mapc
(lambda(x) (macro-apply
(getf x :query)
(getf x :params)
(getf x :return))
lst))
有没有更好的方法,或者我错过了什么明显的东西?
【问题讨论】:
-
(macroexpand `(mac1 ,@lst))? -
因为它是来自外部库的宏,并且该库不提供函数。通常,您在函数中调用宏并直接将其参数传递给它。但在我的情况下,在运行时,我反复得到一些参数列表(我事先不知道并且长度不同),我被要求用这些参数调用宏。
-
@melpomene 我已经更新了我的问题以更好地说明。
-
顺便说一句,您不需要调用 MACROEXPAND。无论如何,EVAL 都会这样做。
-
一般是这样的。请注意,EVAL 可能不会编译并使用解释器来运行它。还需要解析重复的查询/...每次使用它们时。
标签: macros common-lisp