Destructuring

;; Sequential destructuring
(let [[a b c] [1 2 3]] (+ a b c))                  ; 6
(let [[first-item & rest-items] [1 2 3 4]] rest-items)   ; (2 3 4)
(let [[a _ c] [1 2 3]] [a c])                      ; [1 3]
(let [[a b :as all] [1 2 3]] all)                  ; [1 2 3]
(let [[[x y] [z]] [[1 2] [3]]] [x y z])            ; [1 2 3]: nested

;; Associative destructuring
(let [{name :name age :age} {:name "Ana" :age 30}] name)   ; "Ana"
(let [{:keys [name age]} {:name "Ana" :age 30}] (str name " " age))
(let [{:keys [name email] :or {email "none"}} {:name "Bo"}] email)   ; "none"
(let [{:strs [host port]} {"host" "localhost" "port" 80}] host)      ; string keys
(let [{:user/keys [id]} {:user/id 7}] id)          ; namespaced keys
(let [{:keys [a] :as m} {:a 1 :b 2}] m)            ; whole map

;; In function parameters
(defn describe [{:keys [name age] :or {age "unknown"}}]
  (str name " is " age))
(describe {:name "Cy"})                            ; "Cy is unknown"

(defn first-two [[a b]] [a b])

;; Nested map destructuring
(let [{{:keys [city]} :address} {:address {:city "Pune"}}] city)   ; "Pune"

;; In loops
(doseq [[k v] {:a 1 :b 2}] (println k v))
(for [{:keys [name]} [{:name "a"} 
…