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 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
-~----------~----~----~----~------~----~------~--~---

Reply via email to