Is Clojure Short Circuit Logic?

In many languages, if you write something line by line

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?

Thank!

+5
source share
6 answers

Since you answered your own question, note that although in your example b and c cannot be evaluated in a call (or abc), let binding is evaluated before that, therefore too-lazy for optimization-this-function call is evaluated in any case. Clojure is not so lazy.

: , , or, :

(or (simple-function args)
    (complex-function args)
    (too-lazy-to-optimize-this-function args))
+12

, , REPL:

user=> (or true (do (println "hello") true))
true
user=> (or false (do (println "hello") true))
hello
true
+10

, :



:

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

exprs , . , , . () .

( .)

and , .

+4

, , "".

:   " exprs , . , , . () nil."

+1

, Clojure .

Clojure/ Lisps , , . , .

NAND Clojure:

(defmacro nand 
  ([x] 
    `(not ~x))              ; NAND is equivalent to NOT for one argument
  ([x & xs] 
    `(let [nand# (not ~x)]
       (if nand# 
         true               ; short circuit if we can prove the nand is true
         (nand ~@xs)))))    ; continue with the other expressions otherwise

(nand true true)
=> false

(nand false (println "Expression with a side effect!"))
=> true
+1
if (foo() || bar() || foobar()) { /* do stuff */ }

(if (or (foo) (bar) (boobar)) (comment do stuff))

(when (or (foo) (bar) (boobar)) (comment do stuff))
0

All Articles