如何将可选的宏参数传递给函数
问题描述:
Clojure宏的noob在这里。我有一个带有一些可选参数的函数,例如如何将可选的宏参数传递给函数
(defn mk-foo [name & opt]
(vec (list* name opt)))
给这个:
user> (mk-foo "bar" 1 2 3)
["bar" 1 2 3]
我想编写一个宏,其采用相同的可选参数和透明地传递他们的mk-foo
调用。到目前为止,我有这样的:
(defmacro deffoo [name & opt]
`(def ~name ~(apply mk-foo (str name) opt)))
其中有预期的效果:
user> (macroexpand '(deffoo bar 1 2 3))
(def bar ["bar" 1 2 3])
采用apply
拼合列表opt
感觉笨拙。有没有一种惯用的方式来做到这一点?我猜[email protected]
是必要的,但我不能得到引用的权利。非常感谢。
答
在这种情况下,你对使用apply的直觉很好。当你有一个引用的表格`,然后unqote所有这些可以帮助考虑将未引用的内容移动到最小的部分或列表中。这避免了使用代码来生成可以简单写入的表单。
user=> (defmacro deffoo [name & opt] `(def ~name [~(str name) [email protected]]))
#'user/deffoo
user=> (macroexpand '(deffoo "bar" 1 2 3))
(def "bar" ["bar" 1 2 3])
,并在这里它与调用MK-FOO:
(defmacro deffoo [name & opt] `(def ~name (mk-foo ~(str name) [email protected])))
#'user/deffoo
user=> (macroexpand '(deffoo "bar" 1 2 3))
(def "bar" (user/mk-foo "bar" 1 2 3))
在第二种情况下,我们移动在一个水平~
,让呼叫MK-FOO留报价,只是所享有建立参数列表所需的参数(使用拼接 - 无引号,如你所怀疑的)
我不是特别擅长clojure,但它对我来说看起来很好! – 2012-01-12 22:02:03