Here is one way to do it called update-in+. It returns a vector consisting of the new udpated value, like update-in does, followed by the original value (in case you might want to see that for some reason), followed by the updated value.
(defn update-in+ ([m [k & ks] f & args] (if ks (let [[new-map old-val new-val] (apply update-in+ (get m k) ks f args)] [(assoc m k new-map) old-val new-val]) (let [old-val (get m k) new-val (apply f old-val args)] [(assoc m k new-val) old-val new-val])))) Andy On Thu, Apr 26, 2012 at 9:19 AM, Ambrose Bonnaire-Sergeant < abonnaireserge...@gmail.com> wrote: > Hi, > > You shouldn't need mutation for such a function. > > If you look at the source of update-in, it's fairly straightforward. > > (defn update-in > ([m [k & ks] f & args] > (if ks > (assoc m k (apply update-in (get m k) ks f args)) > (assoc m k (apply f (get m k) args))))) > > Just create another function that returns a vector of the result of > applying f, and the update-in result. It should be easy starting from > update-in's source. > > (I'm not aware of an existing solution) > > Thanks, > Ambrose > > On Fri, Apr 27, 2012 at 12:00 AM, blais <goo...@furius.ca> wrote: > >> Hi, >> I have this use-case for (update-in) which keeps showing up in my code >> which I don't have a solution for and I'm wondering if there isn't a >> solution. >> How do I _efficiently_ obtain the new value created by an invocation of >> (update-in), that is, without having to get the modified value by lookups >> in the new map? >> >> Simplified example: >> >> (def m {:planet {:country {:state {:city {:borough 4}}}}}) >> >> (let [mm (update-in m >> [:planet :country :state :city :borough] >> (fn [old] (if (nil? old) 0 (inc old))))] >> (get-in mm [:planet :country :state :city :borough])) >> >> (update-in) returns the new/modified map, but what I want is to obtain >> the new count returned by the anonymous function. >> Having to call (get-in) right after is inefficient. >> >> This is obviously a contrived example for this question, but I have a lot >> of real use cases for this (where at the top level of my app I have a ref >> for a deep structure which changes as a response to network events). >> >> Is there an idiomatic way to do this without having to resort to >> mutability? >> (The only solution that comes to my mind is to wrap up update-in and the >> modifier function with a special version that updates a local mutable and >> return both the new map and the new object.) >> Nasty? >> >> Thank you, >> >> >> >> -- >> 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 > > > -- > 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 > -- 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