In Clojure, how to destructure all the keys of a map?

Not really, and it wouldn't be a good idea. Imagine:

(let [{:all-the-keys} m]
  (foo bar))

Are foo and bar globals? Locals? Keys you should extract from m? What should this code do if m sometimes contains a foo key, and foo is also a global function? Sometimes you call the global, and sometimes you call the function stored in m?

Ignoring the technical problems (which could be overcome), it is really a disaster for readability and predictability. Just be explicit about what keys you want to pull out; if you frequently want to pull out the same ten keys, you can write a simple macro like (with-person p body) that simplifies that common case for you.


This question is pretty old so you've probably forgotten about it, but it came up on google when I was trying to do the same thing, so if I post my solution it might help someone else out.

(defmacro let-map [vars & forms]
  `(eval (list 'let (->> ~vars keys
                         (map (fn [sym#] [(-> sym# name symbol) (~vars sym#)]))
                         (apply concat) vec)
               '~(conj forms 'do))))

This basically transforms the map {:cpp 88 :js 90} into the binding form [cpp 88 js 90] then constructs a let binding, along with performing some eval-jitsu to make sure that this happens at run time.

(def test-map {:cpp 88 :js 90})
(let-map test-map
  (println js)
  (println cpp))
;=> 90
;=> 88

Tags:

Clojure