Clojure 关于和宏的来源

Clojure 关于和宏的来源,clojure,Clojure,我正在浏览clojure.core的源代码: (defmacro and ([] true) ([x] x) ([x & next] `(let [and# ~x] (if and# (and ~@next) and#)))) 为什么不 (defmacro and ([] true) ([x] x) ([x & next] `(if ~x (and ~@next) ~x))) 因为参数x是一种形式,可以是任何表达式,可以在中计算

我正在浏览clojure.core的源代码:

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

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

因为参数
x
是一种形式,可以是任何表达式,可以在
中计算两次(如果~x(和~@next)~x))
let
对其求值一次,然后使用值
x

因此,实际的代码避免了对参数进行两次求值的影响,尤其是副作用



@amalloy指出,只有当第一个实例的计算结果为false(y)时,才会计算
中形式
x
(if~x(and~@next)~x))
的第二个实例

嗯,这是一种表达,而不仅仅是“可能”。“可能”是指它可能被评估两次(特别是,如果它是假的,它将被评估两次)。@amalloy Yes。你的第二点很重要。虽然我正式地知道,如果<代码>没有事先计算它的<代码>那么<代码>和<代码>其他<代码>参数,那么它暂停表单动画的想法并没有强迫自己回家。我试图在不模糊要点的情况下纠正答案。