liveBook · Manning

Short-circuit evaluation

As explained in Clojure: The Essential Reference

Short-circuit evaluation is an evaluation strategy that skips operands whose results cannot affect the overall logical result.

Short-circuit evaluation stops a logical chain as soon as later expressions cannot change its result. In Clojure, `and` and `or` evaluate expressions from left to right. They return operand values, not necessarily Boolean values. section 3.2.2

The stopping rules differ:

  • `and` stops at the first `false` or `nil` and returns it; otherwise it returns the last value. With no arguments it returns `true`. section 3.2.2
  • `or` stops at the first truthy value and returns it; otherwise it returns the last value. With no arguments it returns `nil`. section 3.2.2

Truthiness affects where evaluation stops

`(and 1 "ok")` returns `"ok"`; `(or nil 0 "fallback")` returns `0`. Zero is truthy in Clojure, as are empty strings and lists. Only `false` and `nil` are falsey. section 3.2 section 3.2.2

Supply a default only when needed

`(let [port (or (:port opts) 8080)] (str "starting server on localhost:" port))` uses the supplied port when it is truthy and otherwise uses `8080`. For `{:port 9001}`, the result is `"starting server on localhost:9001"`; for `{}`, it is `"starting server on localhost:8080"`. section 3.2.2

(defn path [s]
  (let [s (and s (.trim s))]  ; #1
    (and
      (seq s)                 ; #2
      (subs s 0 (.lastIndexOf s "/")))))

(path "/tmp/exp/lol.txt")
;; "/tmp/exp"

(path "   ")
;; nil

(path "")
;; nil

(path nil)
;; nil

A file-path example uses `and` to avoid trimming `nil`, then uses `seq` to reject an empty trimmed string before extracting the directory. section 3.2.2

For a reusable combination of predicates, use `every-pred` or `some-fn`: they stop on a falsey or truthy predicate result, respectively. Writing `(and number? pos? odd?)` does not create a combined predicate; `and` evaluates those function values as expressions. Use `(every-pred number? pos? odd?)` when each predicate must run on the eventual input. section 2.2.9

How Clojure: The Essential Reference covers it

How deep it goes
Details return values, zero-argument cases, practical guards, and macro expansion rather than a general evaluation model.
Examples
Demonstrates file-path guarding, a default server port, predicate filtering, and spam detection.
What it assumes
Introduces Clojure truthiness, including its two falsey values, before applying it to expression chains.
What you can do after
Apply it via Clojure `and` and `or` for guards and defaults, or via `every-pred` and `some-fn` for combined predicates.
How it connects
Links Clojure truthiness, Boolean operators, Java interoperability, and predicate combinators `every-pred` and `some-fn`.

Also explained in

Compare how 3 books explain short-circuit evaluation →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.