On Fri, Jan 6, 2012 at 3:02 PM, Jozef Wagner <jozef.wag...@gmail.com> wrote: > Consider this contrived piece of code: > > (def aval (atom {:dumped false :contents "hello world"})) > > (defn update! > [item] > (when-not (:dumped item) > (spit "a.out" (:contents item) :append true) > (assoc item :dumped true))) > > How should I correctly call update! ? Each of following two calls have > drawbacks. > > (swap! aval update!) ;; update! can be called more than once > > (let [new-val (update! aval)] > ;; aval can be changed in between from other thread > (reset! aval new-val)) > > Best, > Jozef >
Jozef, I think you can solve this by adding a little more info and keeping the update function and side effects separate: (def aval (atom { :contents "hello world" })) (defn update-item [{:keys [dumped] :as item}] (assoc item :dumped true :needs-dump (not dumped))) (let [{:keys [needs-dump contents]} (swap! aval update-item)] (if needs-dump (spit "a.out" contents :append true))) Whoever gets to aval first while it hasn't been dumped will see needs-dump as true and write the file. Depending on your requirements, if the file write fails, you'll might need to do some extra work to put aval back in a state consistent with reality. Hope this helps, Dave -- 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