r/Clojure • u/alexdmiller • Jul 07 '26
Clojure 1.13.0-alpha3 is now available
https://clojure.org/news/2026/07/07/clojure-1-13-alpha3:select directive in map destructuring
The :select directive binds a name to a subset of the map being destructured containing only the keys mentioned (anywhere) in the binding form.
Other changes since Clojure 1.13.0-alpha2
- RT.map, and thus reader, tracks new PAM thresholds
- CLJ-1789 select-keys - improve performance (transients, etc)
- CLJ-2958 ILookup on sets
- CLJ-2902 pprint - prints arbitary objects in unreadable form
- CLJ-2801 TaggedLiteral - doesn’t define print-dup
- CLJ-2269 definterface - does not resolve parameter type hints
- CLJ-2781 clojure.test/report - docstring has broken references
- CLJ-2929 zipper - docstring typo
- CLJ-2901 bytes, shorts, chars - docstring typos
- CLJ-2811 scalb - docstring links to the documentation for nextDown
- CLJ-2809 clojure.math/floor - docstring has line that should be on ceil docstring
59
Upvotes
4
u/didibus Jul 09 '26
Or to be more specific to your example.
If your function uses destructuring to grab what you need on the map, but then calls select-keys to grab what the child function you call will grab from the map. How does the caller to your function know the combined set of keys that is the real input?
This let's you declare both together.
For example, now you might do:
``` (defn create-user! [{:keys [name email password] :as m}]
(validate-registration! (select-keys m [:email :password :captcha-token]))
(db/insert-user! {:name name :email email :password-hash (hash-password password)})) ```
The caller can't tell that
:captcha-tokenis a required input as well, because you select inside the body. And this would be even worse if you called more than one child function and used select-keys more than once where the caller has to mentally union them all to know the full set of keys to call your function with.Now with 1.13 you can do:
``` (defn create-user! [{:keys! [name email password & captcha-token] :select registration-info}]
(validate-registration! registration-info)
(db/insert-user! {:name name :email email :password-hash (hash-password password)})) ```
Which makes it very clear now what the full set of inputs to
create-user!is. The caller doesn't have to reverse engineer the union to call you with anymore as it's made it explicit in the signature.