惯用语`和`& Clojure中的`或`函数(不是宏)

时间:2015-01-22 04:33:17

标签: clojure boolean

听起来很奇怪,我正在寻找Clojure中andor宏的函数版本。

为什么呢?我很好奇。

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

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

我希望后置条件检查victor是否返回向量或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 %))]}
  ;; ...
  )
但是,如果功能存在,我仍然很好奇。

3 个答案:

答案 0 :(得分:3)

通常,andor函数是不合需要的,因为它们不能使用短路。请考虑以下代码:

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

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

答案 1 :(得分:3)

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

答案 2 :(得分:1)

@Triangle Man是对的。短路不起作用,但您可以定义自己的功能版本:

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=>