Clojure有短路逻辑吗?

Joe*_*oel 5 optimization clojure short-circuiting

在许多语言中,如果你写一些东西

if (foo() || bar() || foobar()) { /* do stuff */ }
Run Code Online (Sandbox Code Playgroud)

并且foo()返回true,然后不会计算bar()和foobar().

假设我有以下Clojure代码:

(let [a (simple-function args)
      b (complex-function args)
      c (too-lazy-to-optimize-this-function args)]
  (or a b c))
Run Code Online (Sandbox Code Playgroud)

如果计算结果为true,那么b和c也会被评估,还是会被忽略?

谢谢!

Joo*_*aat 12

既然您回答了自己的问题,请注意虽然在您的示例中,b和c可能未在(或abc)调用中进行求值,但在此之前会评估let绑定,以便评估过于懒惰的优化此函数调用无论如何.Clojure并不像那样懒惰.

要明确:要有条件地评估函数调用,你需要在调用中放置评估它们的表达式or,基本上:

(or (simple-function args)
    (complex-function args)
    (too-lazy-to-optimize-this-function args))
Run Code Online (Sandbox Code Playgroud)

  • 它不是一个陷阱,而是你必须要理解除了懒惰序列以及对它们起作用的函数之外所有东西都是渴望的.'或'短路,因为它是一个宏,它扩展到http://bit.ly/u8xnms.如果它是一个函数,它将评估它的参数.相反,它宏扩展到if,这是一种特殊的形式和短路. (4认同)

Sea*_*lan 11

另一个答案都很好,但如果有疑问,你可以随时在REPL上测试它:

user=> (or true (do (println "hello") true))
true
user=> (or false (do (println "hello") true))
hello
true
Run Code Online (Sandbox Code Playgroud)