我开始使用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,但仍然不清楚为什么会如此。
答案 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
不仅仅适用于动态语言中的布尔值。我花了很长时间才意识到这一点。