You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: content/guides/destructuring.adoc
+11-26Lines changed: 11 additions & 26 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -273,9 +273,9 @@ Associative destructuring, however, also allows you to supply a default value if
273
273
;= Category not found
274
274
----
275
275
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.
276
+
To supply default values for keys that are not present in the input map, you can use the `:or` directive, whose value is a map of binding names or [since 1.13] keys to default values. Thus here `"Category not found"` will be used as the value for the binding category if the key `:category` is not in the input map (`client`). Note that if an unadorned symbol is used as a key in the `:or` map but not yet in any binding the entry is a no-op.
277
277
278
-
You may also specify values either via explicit keys in the `:or` map, which was added in Clojure 1.13.
278
+
The next example uses `:category` as an explicit key rather than the binding name `category` in the `:or` map.
279
279
280
280
[source,clojure]
281
281
----
@@ -284,7 +284,7 @@ You may also specify values either via explicit keys in the `:or` map, which was
284
284
;= "Category again not found"
285
285
----
286
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.
287
+
If you wish to capture the default values stated in the `:or` map, the `:defaults` directivebinds a name to a map, created during destructuring, of keys to their default values. [since 1.13] 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
288
289
289
[source,clojure]
290
290
----
@@ -304,7 +304,7 @@ If you need access to the entire map, you can use the `:as` key to bind the enti
304
304
;= The name from {:name Super Co., :location Philadelphia, :description The world wide leader in plastic table-ware.} is Super Co.
305
305
----
306
306
307
-
The `:as`, `:or`, and `:defaults` keywords can be combined in a single destructuring.
307
+
The `:as`, `:or`, and `:defaults` keywords can be combined in a single destructuring form:
308
308
309
309
[source,clojure]
310
310
----
@@ -346,7 +346,7 @@ The `:keys` key is for associative values with keyword keys, but there are also
346
346
;= Jane Doe
347
347
----
348
348
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.
349
+
If you want it to be an error to supply a map that is missing certain keys (rather than get `nil` or default values), you can [since 1.13] use the checked versions of the binding directives (`:keys!`, `:strs!`, and `:syms!`) that throw an exception if the required keys are not present.
350
350
351
351
[source,clojure]
352
352
----
@@ -355,20 +355,20 @@ Additionally, since Clojure 1.13 there are checked versions of the binding direc
355
355
;= throws Missing required key: "dob"
356
356
----
357
357
358
-
As of Clojure 1.13, all of the binding directives allow you to specify literal keys after `&`for documentation:
358
+
If you have keys you want to require but don't need to bind, you can list them after `&`, which will check for the presence of the listed keys but not create bindings.
359
359
360
360
[source,clojure]
361
361
----
362
-
(let [{:keys [fred ethel lucy & :ricky]} m] ...
362
+
(let [{:keys! [fred ethel lucy & :ricky]} m] ...
363
363
364
-
(let [{:strs [fred ethel lucy & "ricky"]} m] ...
364
+
(let [{:strs! [fred ethel lucy & "ricky"]} m] ...
365
365
366
-
(let [{:syms [fred ethel lucy & 'ricky]} m] ...
366
+
(let [{:syms! [fred ethel lucy & 'ricky]} m] ...
367
367
----
368
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.
369
+
You can also document additional optional keys that you are not binding in the (:keys, :strs, and :syms) directives using `&`. [since 1.13]
370
370
371
-
Also added in Clojure 1.13 is a new directive `:select` that binds a name to a map, created during destructuring, containing only those keys from the input map, or the defaults if not present in the input, that are used anywhere in the destructuring form (other than in `:or`), including in nested destructuring. Thus it is a (deep) subset of the input augmented by defaults.
371
+
To bind a name to a deep subset of the input map, augmented by defaults, use the `:select` directive. [since 1.13] It includes every key used anywhere in the destructuring form, including nested forms, but not keys used only in `:or`.
372
372
373
373
[source,clojure]
374
374
----
@@ -399,21 +399,6 @@ Associative destructuring can be nested and combined with sequential destructuri
399
399
;= Joe is a Ranger wielding a Longbow
400
400
----
401
401
402
-
With nested destructuring, the use of `:or`, `:defaults`, and `:select` only apply at the level at which they are applied:
(println name "had his name set as a default from the :or map" jdf)
411
-
(println "The default unnamed NPC is" npc))
412
-
;= Joe's :select data is {:weapon "Longbow", :name "Sir Joe", :class "Ranger"}
413
-
;= Sir Joe had his name set as a default from the :or map {:name "Sir Joe"}
414
-
;= The default unnamed NPC is {:class "Farmer", :weapon "Shovel"}
415
-
----
416
-
417
402
=== Keyword arguments
418
403
419
404
One special case is using associative destructuring for keyword-arg parsing. Consider a function that takes options `:debug` and `:verbose`. These could be specified in an options map:
Copy file name to clipboardExpand all lines: content/reference/special_forms.adoc
+7-12Lines changed: 7 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -296,7 +296,7 @@ Map __binding-form__s create bindings by looking up values in collections like m
296
296
->[5 3 6 {:c 6, :a 5}]
297
297
----
298
298
299
-
Since Clojure 1.13, the `:or` directive also allows the use of explicit keys:
299
+
The `:or` maps also accept the input key directly in place of the binding name. [since 1.13]
300
300
301
301
[source,clojure]
302
302
----
@@ -306,7 +306,7 @@ Since Clojure 1.13, the `:or` directive also allows the use of explicit keys:
306
306
->[5 3 42 {:a 5}]
307
307
----
308
308
309
-
Also since Clojure 1.13, Clojure allows you to bind a name to a map of keys mapped to their default values, based on what you've said in `:or` per above:
309
+
To capture the `:or` defaults as a map bound to a name, use the `:defaults` directive. [since 1.13]
310
310
311
311
[source,clojure]
312
312
----
@@ -352,14 +352,7 @@ In the case of using prefixed keys, the bound symbol name is the same as the rig
352
352
-> 42
353
353
----
354
354
355
-
As of Clojure 1.13, associative destructuring directives allow you to specify literal keys after `&` that serve as documentation:
356
-
357
-
[source,clojure]
358
-
----
359
-
(let [{:keys [fred ethel lucy & :ricky]} m] ...
360
-
----
361
-
362
-
There are similar `:strs` and `:syms` directives for matching string and symbol keys, the latter also allowing prefixed symbol keys since Clojure 1.6. The literal keys after `&` for these directives match the form of the keys handled, e.g. `:strs [a & "b"]` and `:syms [a & 'b]`. For `:syms` the use of quote is required to distinguish between a binding name and a literal symbol.
355
+
There are similar `:strs` and `:syms` directives for matching string and symbol keys, the latter also allowing prefixed symbol keys.
363
356
364
357
Clojure 1.9 adds support for directly destructuring many keys (or symbols) that share the same namespace using the following destructuring key forms:
365
358
@@ -379,14 +372,16 @@ Clojure 1.9 adds support for directly destructuring many keys (or symbols) that
379
372
-> [1 2]
380
373
----
381
374
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.
375
+
You can ensure that required keys are present during map destructuring by using the checked variants of the `:keys`/`:syms`/`:strs` binding directives named `:keys!`/`:syms!`/`:strs!`, which throw an exception if any of the specified keys are missing from the destructured map. [since 1.13] These checked directives also accept `&`, after which you may list additional keys that are still required and checked, but not bound to a local name.
383
376
384
377
[source,clojure]
385
378
----
386
379
(let [{:keys! [fred ethel lucy & :ricky]} m] ... ;; m must have keys :fred, :ethel, :lucy, and :ricky
387
380
----
388
381
389
-
As of Clojure 1.13, supports a directive `:select` that binds a name to a map, created during destructuring, containing only those keys from the input map, or the defaults if not present in the input, that are used anywhere in the destructuring form (other than in `:or`), including in nested destructuring. Thus it is a (deep) subset of the input augmented by defaults.
382
+
The literal keys after `&` for these directives should match the form of the keys handled, e.g. `:strs [a & "b"]` and `:syms [a & 'b]`. For `:syms` the use of quote is required to distinguish between a binding name and a literal symbol. In the unchecked directives `:keys`, `:strs`, and `:syms`, `&` serves only as documentation: the listed keys are neither bound nor checked for presence. [since 1.13]
383
+
384
+
To bind a name to a deep subset of the input map, augmented by defaults, use the `:select` directive. [since 1.13] It includes every key used anywhere in the destructuring form, including nested forms, but not keys used only in `:or`.
0 commit comments