Skip to content

Commit 0668641

Browse files
committed
WiP. :select needed
1 parent d043d02 commit 0668641

2 files changed

Lines changed: 47 additions & 5 deletions

File tree

content/guides/destructuring.adoc

Lines changed: 46 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -273,7 +273,25 @@ Associative destructuring, however, also allows you to supply a default value if
273273
;= Category not found
274274
----
275275

276-
The value for `:or` is a map where the bound symbol (here `category`) is bound to the expression `"Category not found"`. When category is not found in `client`, it is instead found in the `:or` map and bound to that value instead.
276+
The value for `:or` is a map where the bound symbol (here `category`) is bound to the expression `"Category not found"`. When category is not found in `client`, it is instead found in the `:or` map and bound to that value instead. When used this way, the default is for the key associated with that binding name. If you haven't yet used that binding name in a binding elsewhere, it is not associated with any key and the entry is a no-op.
277+
278+
You may also specify values either via explicit keys in the `:or` map, which was added in Clojure 1.13.
279+
280+
[source,clojure]
281+
----
282+
(let [{category :category, :or {:category "Category again not found"}} client]
283+
(println category))
284+
;= "Category again not found"
285+
----
286+
287+
If you wish to capture the default values stated in the `:or` map, the `:defaults` directive, added in Clojure 1.13, binds a name to a map, created during destructuring, of keys to their default values. You would use `:defaults` when you want those same default values for some purpose later in your code, and don't want to restate them.
288+
289+
[source,clojure]
290+
----
291+
(let [{category :category, :or {category "Category not found", :comms "email"}, :defaults df} client]
292+
(println df))
293+
;= {:category "Category not found", :comms "email"}
294+
----
277295

278296
In sequential destructuring, you generally bind unneeded values with an `_`. Since associative destructuring doesn't require traversing the entire structure, you can simply omit any keys you don't plan on using from the destructuring form.
279297

@@ -286,16 +304,18 @@ If you need access to the entire map, you can use the `:as` key to bind the enti
286304
;= The name from {:name Super Co., :location Philadelphia, :description The world wide leader in plastic table-ware.} is Super Co.
287305
----
288306

289-
The `:as` and `:or` keywords can be combined in a single destructuring.
307+
The `:as`, `:or`, and `:defaults` keywords can be combined in a single destructuring.
290308

291309
[source,clojure]
292310
----
293311
(def my-map {:a "A" :b "B" :c 3 :d 4})
294-
(let [{a :a, x :x, :or {x "Not found!"}, :as all} my-map]
312+
(let [{a :a, x :x, :or {x "Not found!"}, :as all, :defaults df} my-map]
295313
(println "I got" a "from" all)
296-
(println "Where is x?" x))
314+
(println "Where is x?" x)
315+
(println "Defaults are" df))
297316
;= I got A from {:a "A" :b "B" :c 3 :d 4}
298317
;= Where is x? Not found!
318+
;= Defaults are {:x Not found!}
299319
----
300320

301321
You might have noticed that our original example still contains redundant information (the local binding name and the key name) in the associative destructuring form. The `:keys` key can be used to further remove the duplication:
@@ -326,6 +346,28 @@ The `:keys` key is for associative values with keyword keys, but there are also
326346
;= Jane Doe
327347
----
328348

349+
Additionally, since Clojure 1.13 there are checked versions of the binding directives named `:keys!`, `:strs!`, and `:syms!` that throw an exception if the keys specified are not present in the destructured map.
350+
351+
[source,clojure]
352+
----
353+
(let [{:strs! [first-name last-name dob]} string-keys]
354+
(println first-name last-name))
355+
;= throws Missing required key: "dob"
356+
----
357+
358+
As of Clojure 1.13, all of the binding directives allow you to specify literal keys after `&` for documentation:
359+
360+
[source,clojure]
361+
----
362+
(let [{:keys [fred ethel lucy & :ricky]} m] ...
363+
364+
(let [{:strs [fred ethel lucy & "ricky"]} m] ...
365+
366+
(let [{:syms [fred ethel lucy & 'ricky]} m] ...
367+
----
368+
369+
The use of `&` in the unchecked versions allow you to specify accepted keys, but its use in the checked variants is more strict as the keys specified are still required and will throw if not present.
370+
329371
Associative destructuring can be nested and combined with sequential destructuring as needed.
330372

331373
[source,clojure]

content/reference/special_forms.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ Clojure 1.9 adds support for directly destructuring many keys (or symbols) that
379379
-> [1 2]
380380
----
381381

382-
As of Clojure 1.13, you can now ensure that required keys are bound during map destructuring by using the new checked variants of the `:keys`/`:syms`/`:strs` directives - `:keys!`/`:syms!`/`:strs!`, which will throw if the key is not present. These checked directives also support the use of `&` and will check the presence of the specified keys in the destructured map.
382+
As of Clojure 1.13, you can now ensure that required keys are bound during map destructuring by using the new checked variants of the `:keys`/`:syms`/`:strs` binding directives - `:keys!`/`:syms!`/`:strs!`, which will throw an exception if the keys specified are not present in the destructured map. These checked directives also support the use of `&` and will check the presence of the specified keys in the destructured map.
383383

384384
[source,clojure]
385385
----

0 commit comments

Comments
 (0)