Destructuring is a convenient feature that makes it easy to create local bindings (not variables!) By separating complex data structures (seq-ables, such as vectors or associations, such as hash maps), as described here .
Take the following example:
(let [v [1 2 3 4 5 6] v_0 (first v) v_1 (nth v 1) v_rest (drop 2 v) m {:a 1 :b 2} m_a (get m :a) m_b (get m :b) m_default (get m :c "DEFAULT")] (println v, v_0, v_1, v_rest, m, m_a, m_b, m_default))
Then, the above code can be simplified using destructive bindings such as:
(let [[v_0 v_1 & v_rest :as v] [1 2 3 4 5 6] {m_a :a m_b :b m_default :c :or {m_default "DEFAULT"} :as m} {:a 1 :b 2}] (println v, v_0, v_1, v_rest, m, m_a, m_b, m_default))
Destruction patterns can be used in let bindings and functional parameters ( fn , defn , letfn , etc.), as well as in macro returns let bindings containing such destruction patterns.
One important use of the if-let and when-let macros should be noted. The if always evaluated in its entirety, even if the destructed bindings themselves are evaluated as nil :
(if-let [{:keys [ab]} {:c 1 :d 2}] (println ab) (println "Not this one"))