Clojure宏扩展

Ham*_*aya 3 lisp macros clojure

我正在研究一个宏,我试图找出如何避免某些形式的扩展,以下面的宏和宏为例,


(defmacro and
  ([] true)
  ([x] x)
  ([x & next]
   `(let [and# ~x]
      (if and# (and ~@next) and#))))

扩展后,

(mexpand-all '(and 1 2 3))
Run Code Online (Sandbox Code Playgroud)

变,


(let* [and__973__auto__ 1]
      (if and__973__auto__
        (let* [and__973__auto__ 2]
              (if and__973__auto__ 3 and__973__auto__))
        and__973__auto__))

在这种情况下,我需要做的是停止扩展到let*.

ama*_*loy 5

咦?目前还不清楚"停止" let扩张的意思.let是一个在clojure.core中定义的宏,编译器一无所知:它只能理解let*.如果你的宏扩展为一个let(某种程度上)拒绝进一步扩展,它将无法编译.

如果你想单独检查宏的输出,而不用担心递归扩展它,你应该使用macroexpandmacroexpand-1代替这个mexpand-all东西.我不知道从何mexpand-all而来,但当我需要这样的东西时,我会使用clojure.walk/macroexpand-all.