Clojure "and" 宏作为符号

Clojure "and" macro as a symbol

为什么下面的语句return会有不同的结果?此外,如何编写第二条语句来接收预期的 false 结果?

(clojure.core/and false true)
=> false

((resolve 'clojure.core/and) false true)
=> true

freenode 上#clojure 的好心人帮我解答了。 首先,应该尽量避免在 运行 时解析宏。 其次,宏函数被实现为除了 any (&) args 之外还接受两个参数的函数。因此,上面第二条语句的正确写法是

((resolve 'clojure.core/and) nil nil false true) => 
**(clojure.core/let [and__3973__auto__ false] (if and__3973__auto__ (clojure.core/and true) and__3973__auto__))**

由于我们仍在使用宏,它只是将其扩展为代码,而不是返回实际值。 AND 被实现为宏的原因是为了使短路成为可能。 从REPL可以看出:

(defmacro and
  "Evaluates exprs one at a time, from left to right. If a form
  returns logical false (nil or false), and returns that value and
  doesn't evaluate any of the other expressions, otherwise it returns
  the value of the last expr. (and) returns true."
  {:added "1.0"}
  ([] true)
  ([x] x)
  ([x & next]
   `(let [and# ~x]
      (if and# (and ~@next) and#))))

如果没有宏,AND 函数将计算所有给定的谓词而不会短路。 在我的特殊情况下,这正是我所需要的; AND 和 OR 非短路功能。 以下是这两个功能,以防有人需要它们:

(defn and* [& xs] (every? identity xs))
(defn or* [& xs] (not= (some true? xs) nil))