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 [email protected]
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
-~----------~----~----~----~------~----~------~--~---