Clojure 中惯用的 `and` 和 `or` 函数(不是宏)

Idiomatic `and` & `or` functions (not macros) in Clojure

虽然听起来很奇怪,但我正在寻找 Clojure 中 and and or 宏的函数版本。

为什么?一方面我很好奇。

其次,我想在 precondition and postcondition 检查中使用 or。这不起作用:

(defn victor
  [x]
  {:post (or (nil? %) (vector %))}
  ;; ...
  )

我想让后置条件检查 victor returns 是矢量还是 nil,但它失败了:

#<CompilerException java.lang.RuntimeException: Can't take value of a macro: #'clojure.core/or, compiling:(test/test.clj:10:1)>

我认为 bit-andbit-or 不是我想要的。

更新:此语法没有错误:

(defn victor
  [x]
  {:post [(or (nil? %) (vector %))]}
  ;; ...
  )

不过我还是很好奇函数是否存在。

一般来说,andor 函数是不可取的,因为它们不能使用短路。考虑以下代码:

(and false some-expensive-fn)
(or true some-expensive-fn)

andor作为宏上面的代码不会执行some-expensive-fn,因为不需要确定表达式的整体真值。在函数表达式中,参数在传递给函数之前被计算,但在宏中它们不是。

我认为标准方法只是将 andor 包装在函数中,例如(fn [x y] (or x y))。在某些情况下,另一个功能会起作用。例如,clojure docs for and 中的注释建议使用 (every? identity [true false])somenot-every?not-any?的用法类似。

@三角男说的对。短路不起作用,但是您可以定义自己的函数版本:

user=> (defn && [x y] (and x y))
#'user/&&
user=> (&& true false)
false
user=> (&& true true)
true
user=> (defn || [x y] (or x y))
#'user/||
user=> (|| true false)
true
user=> (|| true true)
true
user=> (|| false false)
false
user=>