如果我这样做,例如:
(defmacro qqq [] '(toString [this] "Qqq"))
(reify Object (qqq))
由于reify
看到(qqq)
而不是(toString [this] "Qqq")
而失败。
usual solution是一个用我自己的东西包裹“reify”调用的宏,但它更长,更具侵入性。
如何使我的宏更强大,以便首先扩展通常的宏?
期待类似的事情:
(defmacro ^{:priority 100500} qqq [] '(toString [this] "Qqq"))
(reify Object (qqq))
或
(defmacro qqq [] '(toString [this] "Qqq"))
(expand-first #{qqq} (reify Object (qqq)))
答案 0 :(得分:7)
在读取时(宏扩展时间之前)有一个读取器宏来评估事物。
(defn qqq [] '(toString [this] "Qqq"))
(reify Object #=(qqq))
我从来没有在"真实"代码,我想大多数人会认为这是一个黑客,但如果你需要它就会在那里。
答案 1 :(得分:1)
强制给定用户宏首先展开的宏(需要clojure.walk
):
(defmacro expand-first [the-set & code]
`(do ~@(prewalk
#(if (and (list? %) (contains? the-set (first %)))
(macroexpand-all %)
%) code)))
谁有想法如何让它变得更好?
答案 2 :(得分:0)
这将有效:
(defn reifyx [x y]
(eval `(reify ~x ~y)))
(defn qqq [] '(toString [this] "Qqq"))
(reifyx 'Object (qqq))
我找到了apply-macro。我试了一下,但好像坏了。我在查看apply-macro
时收集的最重要的事情是它使用eval
解决了问题,就像我一样。