Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does Clojure have short-circuit logic?

In many languages, if you write something along the lines of

if (foo() || bar() || foobar()) { /* do stuff */ }

and foo() returns true, then bar() and foobar() will not be evaluated.

Suppose I had the following Clojure code:

(let [a (simple-function args)
      b (complex-function args)
      c (too-lazy-to-optimize-this-function args)]
  (or a b c))

If a evaluates to true, will b and c also be evaluated, or will they be ignored?

Thanks!

like image 257
Joel Avatar asked Nov 18 '11 23:11

Joel


4 Answers

Since you answered your own question, note that though in your example b and c may not evaluated in the (or a b c) call, the let binding is evaluated before that so the too-lazy-to-optimize-this-function call is evaluated anyway. Clojure isn't as lazy as that.

To be clear: to conditionally evaluate the function calls, you need to put the expression evaluating them in the or call, basically:

(or (simple-function args)
    (complex-function args)
    (too-lazy-to-optimize-this-function args))
like image 161
Joost Diepenmaat Avatar answered Nov 15 '22 06:11

Joost Diepenmaat


The other answers all good, but when in doubt, you can always just test it out on the REPL:

user=> (or true (do (println "hello") true))
true
user=> (or false (do (println "hello") true))
hello
true
like image 27
Sean Nilan Avatar answered Nov 15 '22 04:11

Sean Nilan


When in doubt, consult the documentation:

or
macro
Usage:

   (or)  
   (or x)  
   (or x & next)  

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.

(Emphasis mine.)

The documentation for and shows it behaves in the equivalent way too.

like image 20
Jon Skeet Avatar answered Nov 15 '22 04:11

Jon Skeet


As soon as I finished typing this question, I realized I could just look at the documentation for 'or'.

From the docs: "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."

like image 20
Joel Avatar answered Nov 15 '22 06:11

Joel