为什么clojure运算符不匹配正常的逻辑运算?

时间:2016-01-27 05:15:55

标签: clojure

有人请解释clojure不寻常的操作员吗?

为什么or首先返回true或最后为false?为什么and首先返回false或最后为true?

为什么他们不返回truefalse

3 个答案:

答案 0 :(得分:5)

便利。 Clojure拥抱虚假(零和假都是假的)和真实的(其他一切)。

(or a b c)

更方便
(cond (not (nil? a)) a (not (nil? b)) b (not (nil? c)))

将nil视为false会使表达式变得更复杂,并且返回值往往会使函数和条件更易于组合。例如

(if a b c)

用命令式语言不会返回任何结果。在Clojure中,它返回一个值,因此您可以使用其他表达式组合表达式。

(or (if a b c) (if d e f))

当它们返回值而不是布尔值时,与语言抽象类似或者更容易组合。

(if a (or b c) d)

如果你想要真/假或真或假,那真的归结为。 Truthy / falsey允许更简洁的表达,并且是Clojure的选择。

答案 1 :(得分:3)

这称为short-circuit evaluation。短路运算符评估获得结果所必需的最小参数集。例如,or在至少有一个参数求值为true时求值为true,因此or可以停止("短路")之后评估参数第一个true并将其返回。

许多编程语言(例如C ++,Java)都很常见。 Clojure还利用了其功能,可以将所有值强制转换为布尔值,因此orand可以返回最后一个求值的参数而不是相应的布尔值。

答案 2 :(得分:2)

说明问题所在:

user=> (or [1] nil)
[1]
user=> (or nil [1])
[1]
user=> (and [1] nil)
nil
user=> (and nil [1])
nil

此处[1]truthynilfalsey。 Truthy / false是可以被视为真/假的东西。显然,值true是真实的,值false是假的。

为什么不和&或者返回一个布尔值?

嗯,确实如此:

user=> (or false true)
true
user=> (or true false)
true
user=> (or false false)
false
user=> (or true true)
true
user=> (and false true)
false
user=> (and true false)
false
user=> (and false false)
false
user=> (and true true)
true

所以不是and& or违反了逻辑法则。它们的功能扩展到为其他类型提供支持。其他用法源于此。

短cirtuiting

我忘记提到这一点,直到我看到Alex Filatov's answer。如果and / or的第一个表达式求值为truthy / falsey,则根本不评估第二个参数:

user=> (or true (do (prn :huh) false))
true
user=> (and false (do (prn :huh) true))
false

因此与if&的相似性cond

请注意and& or接受任意数量的参数,同样的规则适用于第三,第四和其他参数。基本上他们从左到右评估他们的论点,尽早失败。