I'm also not completely happy with the usefulness of update-in.
However I don't see how this improves things a lot.

(update-in m [:a :b] + 2) can be written as:
(update-in m [:a :b] (partial + 2)) or
(update-in m [:a :b] #(+ 2 %))

both of which are more readable and more self-documenting IMO.

An extension I have been using is this one:

(update-map m {:a {:b #(+ 2 %)}})

user=> (update-map {:a {:b 3}
                               :c {:d 3}}
                              {:a #(+ 2 %)
                               :c #(conj % {:e 4}})
{:a {:b 5}, :c {:e 4, :d 3}}

in this case any values can be updated by providing a pattern-map
which works like this.  If an element in the pattern-map implements
IFn, it is used to transform the corresponding value in m.
update-map can be used in a reduce when you want to keep state in a
structured fashion in a map. Example:
user=> (reduce (fn [state data]
                         (update-map state {:stddev {:sumofsumsum #(+
(* data data))
                                                                  :sumofsum
#(+ % data)}}))
                       {:stddev {:sumofsumsum 0.0 :sumofsum 0.0}}
                       '(1 2 3))
Unlike loop, the above reduce function can be composed easily as long
as the composed functions use different parts of the map
user=> (reduce #(comp update1 update2)
                       {... some initial state}
                       '(1 2 3 ))
Or without initial state:
user=>(reduce  (fn [state data]
                        (update-map state {:stddev {:sumofsumsum #(+
(or % 0) (* data data))
                                                                 :sumofsum
#(+ (or % 0) data)}})
                       '(1 2 3))

Implementation (not really tested):
(defn update-map
  [m fn-pattern]
  (loop [m m
         [k & ks] (keys fn-pattern)]
    (if k
      (let [k-pat (get fn-pattern k)]
        (cond
         (associative? k-pat)
         (recur (assoc m k (update-map (get m k) k-pat))
                ks)
         (fn? k-pat)
         (recur (assoc m k (k-pat (get m k)))
                ks)
         :else
         (recur (assoc m k k-pat)
                ks)))
      m)))

Alexander

On Oct 13, 6:35 pm, mb <[EMAIL PROTECTED]> wrote:
> Hello,
>
> On 13 Okt., 17:02, "Stephen C. Gilardi" <[EMAIL PROTECTED]> wrote:
>
> >         user=> (update-in m [:a :b] + 2) ; new
> >         {:a {:b 3}}
>
> I think this is a good idea. This would also be in-line with things
> like
> alter and commute.
>
> Sincerely
> Meikel
--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to