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-and
和 bit-or
不是我想要的。
更新:此语法没有错误:
(defn victor
[x]
{:post [(or (nil? %) (vector %))]}
;; ...
)
不过我还是很好奇函数是否存在。
一般来说,and
和 or
函数是不可取的,因为它们不能使用短路。考虑以下代码:
(and false some-expensive-fn)
(or true some-expensive-fn)
用and
和or
作为宏上面的代码不会执行some-expensive-fn
,因为不需要确定表达式的整体真值。在函数表达式中,参数在传递给函数之前被计算,但在宏中它们不是。
我认为标准方法只是将 and
和 or
包装在函数中,例如(fn [x y] (or x y))
。在某些情况下,另一个功能会起作用。例如,clojure docs for and
中的注释建议使用 (every? identity [true false])
。 some
、not-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=>
虽然听起来很奇怪,但我正在寻找 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-and
和 bit-or
不是我想要的。
更新:此语法没有错误:
(defn victor
[x]
{:post [(or (nil? %) (vector %))]}
;; ...
)
不过我还是很好奇函数是否存在。
一般来说,and
和 or
函数是不可取的,因为它们不能使用短路。考虑以下代码:
(and false some-expensive-fn)
(or true some-expensive-fn)
用and
和or
作为宏上面的代码不会执行some-expensive-fn
,因为不需要确定表达式的整体真值。在函数表达式中,参数在传递给函数之前被计算,但在宏中它们不是。
我认为标准方法只是将 and
和 or
包装在函数中,例如(fn [x y] (or x y))
。在某些情况下,另一个功能会起作用。例如,clojure docs for and
中的注释建议使用 (every? identity [true false])
。 some
、not-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=>