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

Reply via email to