Hi Nick, On 25 Jul 2011, at 23:55, cassiel wrote: > > Not very practical, but if you want a safe transaction-free operation > on an atom which returns whether it was changed, you can perhaps hack > it by embedding the change state into the atom itself: > > (def a (atom {:value 45 :changed? false})) > > (defn update-and-check-whether-modified? > [update-fn] > (:changed? > (swap! a (fn [{v :value _ :changed?}] > (let [new-v (update-fn v)] > (if (== v new-v) > {:value new-v :changed? false} > {:value new-v :changed? true})))))) > > (update-and-check-whether-modified? (fn [x] (+ x 1))) > (update-and-check-whether-modified? (fn [x] 70))
Great thinking. I suppose an even more general version of this is to replace the key :changed? with :old-value in the atom: (def a (atom {:value 45 :old-val nil})) (defn update-and-check-whether-modified? [update-fn] (let [updated (swap! a (fn [{v :value o :old-val}] (let [new-v (update-fn v)] {:value new-v :old-val o})))] (= (:old-val updated) (:value updated)))) However, it seems remarkably kludgy to encode the old value into the contract of the atom and *all* update fns when really this could be achieved in a much cleaner fashion with a version of swap! that returned a vec of new and old vals: (defn update-and-check-whether-modified? [update-fn] (let [[new old] (swap-and-also-return-old! (fn [v] (update-fn v)))] (= new old))) Sam --- http://sam.aaron.name -- 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