我一直在查看使用“let”定义的defmacro源代码:
(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]
然而,“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))
有人能解释一下这是怎么工作的吗?我不明白如何在需要“defmacro”已经被定义的情况下定义“defmacro”。(如果这讲得通的话 :)
(fn* let [&form &env & decl] (cons 'let* decl))
这段代码定义了let
函数。它使用了已经在 Clojure 的 Java 代码中定义好的let*
函数。 - Ankur