在clojure中,如何根据自身来定义defmacro?

Zub*_*air 7 clojure

我一直在寻找defmacro的源代码,它的定义中使用了"let":

(def

 ^{:doc "Like defn, but the resulting function name is declared as a
  macro and will be used as a macro by the compiler when it is
  called."
   :arglists '([name doc-string? attr-map? [params*] body]
                 [name doc-string? attr-map? ([params*] body)+ attr-map?])
   :added "1.0"}
 defmacro (fn [&form &env 
                name & args]
             (let [prefix (loop [p (list name) args args]
Run Code Online (Sandbox Code Playgroud)

但是,"let"被定义为宏本身:

(defmacro let
  "binding => binding-form init-expr

  Evaluates the exprs in a lexical context in which the symbols in
  the binding-forms are bound to their respective init-exprs or parts
  therein."
  {:added "1.0", :special-form true, :forms '[(let [bindings*] exprs*)]}
  [bindings & body]
  (assert-args
     (vector? bindings) "a vector for its binding"
     (even? (count bindings)) "an even number of forms in binding vector")
  `(let* ~(destructure bindings) ~@body))
Run Code Online (Sandbox Code Playgroud)

有人可以解释这是如何工作的,因为我无法理解如何根据需要"defmacro"定义的事物来定义"defmacro".(如果这是有道理的:)

Ank*_*kur 8

这是可能的,因为之前界定defmacro在core.clj功能已经存在的定义let,在这个位置(这后来被重新定义).宏只是普通函数,它们绑定的var具有元数据键:macro,true因此在编译时编译器可以区分宏(在编译时执行)和函数,没有这个元键就没有办法区分宏和函数,因为宏本身就是处理S表达式的函数.

  • 不是:`(fn*let [&form&env&decl](cons'let*decl))`..它在哪里取决于let?它定义了let函数.它使用let*,它已经在clojure的java代码中定义 (2认同)

Art*_*ldt 5

recusrive宏工作得很好,并且在clojure语言核心和其他程序中的许多地方都会出现.宏只是返回S-Expressions的函数,因此它们可以像函数一样递归.在let你的例子中,它实际上是caling let*,这是一个不同的函数(在函数名中有*很好),所以虽然递归宏很好,但这不是它们的一个例子

  • 关于明显的循环定义不是问题吗? (2认同)