On Mon, Aug 31, 2009 at 09:14:38AM -0400, Chas Emerick wrote: > > You could define your own let-like construct for this: > > > > > > (defmacro letmap [[m kvs & mkvs] & body] > > (if m > > `(let [~m {} > > ~@(mapcat (fn [[k v]] `(~m (assoc ~m ~k ~v))) kvs)] > > (letmap ~mkvs ~...@body)) > > `(do ~...@body))) > > > > > > Usage: > > > > (letmap [a-map {:a 12 > > :b (* 2 (:a a-map))} > > another-map {:c (:a a-map) > > :d (+ (:b a-map) (:c another-map))}] > > [a-map, another-map]) > > > > -> [{:b 24, :a 12} {:d 36, :c 12}] > > Yeah, I needed something like this a while ago, and came up with this: > > (defmacro let-map > "Equivalent of (let [a 5 b (+ a 5)] {:a a :b b})." > [kvs] > (let [keys (keys (apply hash-map kvs)) > keyword-symbols (mapcat #(vector (keyword (str %)) %) keys)] > `(let [...@kvs] > (hash-map ~...@keyword-symbols)))) > > user=> (let-map [a 5 b (inc a) c [a b] d {:foo c :bar (* a b)}]) > {:a 5, :c [5 6], :b 6, :d {:foo [5 6], :bar 30}} > > The nice thing about it is that you no longer need to use all the > keywords -- the definition of the map's slots becomes far more like > defining sequential bindings in a let.
Thank you all for the answers! I especially like Chas's solution. It didn't occur to me that the redundancy can be eliminated by removing the map and leaving in the let -- that's brilliant! :-) It's much easier to read because one doesn't have to dig into the map to get to the variables, and it looks exactly like the common idiom of interdependent let-bindings. -- Timo --~--~---------~--~----~------------~-------~--~----~ You received this message because you are subscribed to the Google Groups "Clojure" group. To post to this group, send email to clojure@googlegroups.com Note that posts from new members are moderated - please be patient with your first post. To unsubscribe from this group, send email to clojure+unsubscr...@googlegroups.com For more options, visit this group at http://groups.google.com/group/clojure?hl=en -~----------~----~----~----~------~----~------~--~---