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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
To unsubscribe from this group, send email to
[email protected]
For more options, visit this group at
http://groups.google.com/group/clojure?hl=en
-~----------~----~----~----~------~----~------~--~---