为什么(或<falsey value =“”> <falsey value =“”>)返回Clojure中的最终值?</falsey> </falsey>

时间:2015-03-22 19:27:03

标签: clojure boolean

我开始使用Clojure并注意到虽然Clojure的or行为被称为返回第一个truthy值,但将两个falsey值传递给or只返回第二个值:

user=> (or false false)
false

user=> (or false nil)
nil

我的经验主要是在Python中,

>>> False or False
False

这些不相似吗?我理解这是每个http://clojuredocs.org/clojure.core/or的预期行为,并遵循建议调查http://clojuredocs.org/clojure.core/if,但仍然不清楚为什么会如此。

3 个答案:

答案 0 :(得分:5)

我认为doc字符串表明了这一点。它永远不会承诺返回虚假 - 只是为了在没有其他人留下的情况下返回最后一个论点。

user=> (doc or)
-------------------------
clojure.core/or
([] [x] [x & next])
Macro
  Evaluates exprs one at a time, from left to right. If a form
  returns a logical true value, or returns that value and doesn't
  evaluate any of the other expressions, otherwise it returns the
  value of the last expression. (or) returns nil.
nil

另外,我不知道你在哪里知道or有两个论点。

user=> (or nil false false false 1 (println "this is not printed"))
1
user=> (or nil false)
false
user=> (or true)
true
user=> (or)
nil

答案 1 :(得分:1)

我怀疑它是这样做的,因为它更快。

请记住,or是一个宏,它在编译时构建if个表单的级联,当它归结为一个参数时终止(构造一个表单) )只是回到那个论点。

例如,

(or 1 2 3)

...扩展为等同于

的东西
(if 1 1 (if 2 2 3))

如果我们包含jiggery-pokery,确保表达式只被评估一次,那么扩展看起来更像是这样:

(let [__auto__ 1]
  (if __auto__
    __auto__
    (let [__auto__ 2]
      (if __auto__
        __auto__
        3))))

...其中__auto__是一些不会与or的参数中使用的任何符号冲突的符号。

您可以在source code中找到完整的故事。

答案 2 :(得分:0)

实际上很多语言的行为都像javascript,php和python一样。它甚至是javascript中的约定,为函数参数myval = myval or defaultValue;提供默认值。在php中,人们会写do_something() or die();之类的东西。 or不仅仅适用于动态语言中的布尔值。我花了很长时间才意识到这一点。