Macros 如何在其他宏中展开宏';s范围(尝试调试宏)
下面是我能举的最简单的例子:Macros 如何在其他宏中展开宏';s范围(尝试调试宏),macros,clojure,Macros,Clojure,下面是我能举的最简单的例子: (defmacro printer [& forms] `(println ~@forms)) (defmacro adder [s] `(inc ~s)) 它们可以按预期使用: (printer "haha") => "haha" (adder 1) => 2 我可以宏展开查看宏的功能: (macroexpand '(printer 1)) => (clojure.core/println 1) (macroexpand
(defmacro printer [& forms]
`(println ~@forms))
(defmacro adder [s]
`(inc ~s))
它们可以按预期使用:
(printer "haha")
=> "haha"
(adder 1)
=> 2
我可以宏展开
查看宏的功能:
(macroexpand '(printer 1))
=> (clojure.core/println 1)
(macroexpand '(adder 1))
=> (clojure.core/inc 1)
但当它们嵌套时,我得不到我想要的:
(macroexpand '(printer (adder 1)))
=> (clojure.core.println (adder 1))
我希望得到一份工作
=> (clojure.core.println (clojure.core/inc 1))
有什么方法可以扩展嵌套宏吗?
这对我调试一个特定的bug会有很大帮助。你在找什么
谢谢你接受我的回答,我很高兴它有帮助。我忘了补充一点,如果您想完全扩展编译器看到的内容,可以利用clojure分析器的强大功能:
(use '[clojure.tools.analyzer.passes.jvm.emit-form :only [emit-form emit-hygienic-form]]
'[clojure.tools.analyzer.jvm :only [analyze]])
(emit-form (analyze '(printer (adder 1))))
(emit-hygienic-form (analyze '(printer (adder 1))))
上述两种方法给出的结果与macroexpand all
几乎相同,但应涵盖macroexpand all
可能无法完全工作的情况。在您的示例中,它将inc
扩展到inc
定义中的内联函数。另外,emit-form
在检查阴影时非常有用:
(emit-form (analyze '(let [a 1 a a] a)))
;=> (let* [a 1 a a] a)
(emit-hygienic-form (analyze '(let [a 1 a a] a)))
;=> (let* [a__#0 1 a__#1 a__#0] a__#1)
最后,
macroexpand-1
macroexpand all
emit form
和emit-form
都对调试clojure宏很有用。非常感谢!多亏了你,我调试了我的bug:)干杯=)这可能会在将来派上用场。
(emit-form (analyze '(let [a 1 a a] a)))
;=> (let* [a 1 a a] a)
(emit-hygienic-form (analyze '(let [a 1 a a] a)))
;=> (let* [a__#0 1 a__#1 a__#0] a__#1)