我有两个宏。第一个将符号作为唯一参数(因为它已传递给def,因此需要一个符号)。第二个函数接受一个符号列表,并应分别调用每个符号中的第一个。
(defmacro m1 [s]
'(let [f# ... dynamic function definition ...]
(def ~s f#))
第二个宏应获取一个符号列表,并将其传递给第一个,但我无法使其正常工作。我能想到的最好的方法如下:
(defmacro m2 [symbols]
`(for [s# ~symbols] (eval (read-string (str "(name.of.current.namespace/m1 " s# ")")))))
这会强制将
s#
传递给第一个宏之前先对其进行评估。它还使用字符串列表而不是符号列表来调用。这对于我正在使用的库很有用,该库中的所有函数都采用相同的两个第一个参数。我正在尝试在我的命名空间中为某些功能创建包装器功能,这些功能会自动提供所有功能共有的前两个参数值。
有什么想法可以改善吗?
最佳答案
通常,当您询问如何使两个宏协作时,答案是不要同时使它们成为两个宏。我认为我在macro-writing macros上的博文将有助于澄清。对于这种特殊情况,我可能会结合评论中的两个建议:
(defmacro build-simpler-functions [& names]
(cons 'do
(for [name names]
`(def ~(symbol (str "simple-" name))
(partial ~name 5 10))))) ; if you always pass 5 and 10
(build-simpler-functions f1 f2)
这扩展到
(do
(def simple-f1 (clojure.core/partial f1 5 10))
(def simple-f2 (clojure.core/partial f2 5 10)))
看起来基本上就是您想要的。
编辑:如果您“始终”传递的参数对于每个函数都不同,则可以执行以下操作:
(defmacro build-simpler-functions [& names]
(cons 'do
(for [[name & args] names]
`(def ~(symbol (str "simple-" name))
(partial ~name ~@args)))))
(build-simpler-functions [f1 5 10] [f2 "Yo dawg"]) ; expansion similar to the previous
关于macros - 在Clojure中,如何评估另一个宏中的宏参数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5259512/