Threading Macros
;; -> thread-first: inserts each result as the FIRST argument of the next form
(-> {:name "Ana" :age 30}
(assoc :email "[email protected]")
(update :age inc)
(dissoc :name)) ; {:age 31, :email "[email protected]"}
;; ->> thread-last: inserts as the LAST argument (good for sequence functions)
(->> (range 10)
(filter even?)
(map #(* % %))
(reduce +)) ; 120
;; as-> : name the threaded value for arbitrary positions
(as-> [1 2 3] $
(map inc $)
(reduce + $)
(str "Total: " $)) ; "Total: 9"
;; some-> / some->> : stop at the first nil
(some-> {:user {:address nil}} :user :address :city clojure.string/upper-case) ; nil, no NPE
;; cond-> / cond->> : conditionally apply steps
(defn build-query [{:keys [limit sort]}]
(cond-> {:select :*}
limit (assoc :limit limit)
sort (assoc :order-by sort)))
(build-query {:limit 10}) ; {:select :*, :limit 10}
;; doto: call methods on a Java object, return the object
(doto (java.util.ArrayList.) (.add 1) (.add 2)) ; [1 2]