liveBook · Manning

Destructuring assignment

As explained in Clojure: The Essential Reference

Associative destructuring binds values from key-value collections to names according to keys specified in a binding form.

Destructuring binds names to parts of a value where a local binding or function parameter is declared. Associative destructuring selects values by key rather than position, making map-shaped inputs easier to use without repeated lookups. It works in `let`, `fn`, and `defn` binding forms. section 4.6 section 3.1.1 section 2.1.2

Bind map values

`(let [m {:x 1 :y 2} {x :x y :y} m] [x y])` ;; => [1 2] In `{x :x}`, the symbol `x` receives the value at key `:x`. For keyword keys that match the desired local names, `{:keys [x y]}` is shorter. The same map binding can include `:as original` to retain the entire input map. section 4.6

The map binding form provides several ways to choose what remains available in the body:

  • `:keys`, `:strs`, and `:syms` bind values from keyword, string, and symbol keys, respectively. section 4.6
  • `:or` supplies a default when a key is absent, not when its value is explicitly `nil`. With `{:keys [z t] :or {z 3 t 4}}` and `{:z nil}`, the bindings are `z = nil` and `t = 4`. section 4.6
  • `:as` binds a name to the original collection. Binding forms can also nest: a map value may be destructured as another map or as a sequence. section 4.6

Unpack a function argument

`(defn contact-line [{:keys [name] {:keys [city]} :address}] (str name " lives in " city))` Here the function parameter binds `name` from the outer map and `city` from its nested `:address` map. Destructuring in the parameter list avoids separate lookups in the body; `let` is useful when that binding is impractical at the parameter boundary. section 4.6 section 3.1.1

Destructuring is binding syntax, not a series of assignments to an existing map. The standard-library function `destructure` exposes the transformation: it converts binding expressions into ordinary binding pairs used by macros such as `let` and `fn`. For a value threaded through differently positioned operations, `as->` can also use a destructuring form as its binding name; each subsequent value must remain compatible with that form. This `as->` capability is available from Clojure 1.8. section 4.6 section 2.3.5

How Clojure: The Essential Reference covers it

How deep it goes
Defines key-based forms, defaults, aliasing, and nesting, then shows their translation into ordinary binding pairs.
Examples
Uses a map with a missing key and an explicit `nil`, plus a function parameter containing nested map and sequence bindings.
What it assumes
Assumes familiarity with Clojure maps and binding forms while spelling out associative destructuring syntax.
What you can do after
Apply it in `let` or function parameters to unpack map inputs, provide absent-key defaults, and retain the original map.
How it connects
Connects associative destructuring to `let`, `fn`, `defn`, sequential destructuring, and `as->`.

Also explained in

Compare how 6 books explain destructuring assignment →

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Clojure: The Essential Reference. The section links point to the parts of the book it draws on.