如果我这样做,例如:
(defmacro qqq [] '(toString [this] "Qqq"))
(reify Object (qqq))
Run Code Online (Sandbox Code Playgroud)
它失败是因为reify看到(qqq)而不是(toString [this] "Qqq").
在通常的解决办法是,包"具体化"与我自己的事情调用宏,但它更长,更具侵入性.
如何使我的宏更强大,通常的宏首先扩展?
期待像:
(defmacro ^{:priority 100500} qqq [] '(toString [this] "Qqq"))
(reify Object (qqq))
Run Code Online (Sandbox Code Playgroud)
要么
(defmacro qqq [] '(toString [this] "Qqq"))
(expand-first #{qqq} (reify Object (qqq)))
Run Code Online (Sandbox Code Playgroud)
在读取时(宏扩展时间之前)有一个读取器宏来评估事物.
(defn qqq [] '(toString [this] "Qqq"))
(reify Object #=(qqq))
Run Code Online (Sandbox Code Playgroud)
我从未在"真实"代码中看到过这种情况,我认为大多数人会认为这是一种黑客攻击,但如果你需要它,它就会存在.
强制给定用户宏首先扩展的宏(需要clojure.walk):
(defmacro expand-first [the-set & code]
`(do ~@(prewalk
#(if (and (list? %) (contains? the-set (first %)))
(macroexpand-all %)
%) code)))
Run Code Online (Sandbox Code Playgroud)
谁有想法如何让它变得更好?