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


