Clojure - 如何在系统宏之前扩展我的宏?

Vi.*_*Vi. 8 macros clojure

如果我这样做,例如:

(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)

Chr*_*ins 7

在读取时(宏扩展时间之前)有一个读取器宏来评估事物.

(defn qqq [] '(toString [this] "Qqq"))
(reify Object #=(qqq))
Run Code Online (Sandbox Code Playgroud)

我从未在"真实"代码中看到过这种情况,我认为大多数人会认为这是一种黑客攻击,但如果你需要它,它就会存在.


Vi.*_*Vi. 1

强制给定用户宏首先扩展的宏(需要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)

谁有想法如何让它变得更好?