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 [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
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