Truthiness & nil in Clojure
Only nil and false are falsey; or and and turn that into defaults.
;; only nil and false are falsey: 0, "" and [] are all truthy
(defn truthy? [x] (if x true false))
(println (truthy? 0) (truthy? "") (truthy? []) (truthy? nil))
;; or returns its first truthy value; and returns the last one
(def jar {:label "cumin" :grams 0})
(def shelf-name (or (:name jar) (:label jar) "unlabeled"))
(println shelf-name (and (:grams jar) (:label jar)) (and nil :skipped))
;; if-let binds and tests in one step; the else branch sees no binding
(defn jar-note [rack spice]
(if-let [grams (get rack spice)]
(str spice " holds " grams " g")
(str spice " is missing")))
;; when-let skips its body entirely when the binding comes up nil
(when-let [low (seq (filter #(< (val %) 5) {:mace 2 :dill 40}))]
(println "low jars:" (map key low)))
(println (jar-note {"mace" 2} "mace") (jar-note {} "anise"))
How it works
truthy?reports that0,""and[]all count as true.orpicks the first truthy value forshelf-name, whileandreturns the last value when every step holds.if-letbindsgramsonly when the lookup succeeds, andwhen-letskips its body whenseqgives nil.
Keywords and builtins used here
anddefdefnfiltergetifkeymaporprintlnseqstrval
The run, in numbers
- Lines
- 19
- Characters to type
- 815
- Tokens
- 167
- Three-star pace
- 70 tpm
At the three-star pace of 70 tokens a minute, this run takes about 143 seconds.
Step 2 of 3 in Flow & truthiness, step 11 of 27 in Language basics.