我有两个宏。第一个将符号作为唯一参数(因为它已传递给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/

10-12 04:14
查看更多