On Aug 31, 2009, at 6:56 AM, Achim Passen wrote:
>> I would like to simplify it to something like:
>>
>> {:radius 20
>> :diameter (* 2 (% :radius))
>> :circumference (* pi (% :diameter))}
>>
>> where % is the map itself.
>
> 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.
- Chas
--~--~---------~--~----~------------~-------~--~----~
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
-~----------~----~----~----~------~----~------~--~---