On 21 February 2010 09:37, Michael Wood <esiot...@gmail.com> wrote: > (defn print-info [] > (let [[src dst] (dosync > (ensure source-account) > (ensure dest-account) > �...@source-account @dest-account])] > (println src) > (println dst)))
This can be simplified to (defn print-info [] (let [[src dst] (dosync [(ensure source-account) (ensure dest-account)])] (println src) (println dst))) ensure returns the in-trasaction value of the ref. There's no guarantee that the refs won't be changed a split second after the transaction, of course... To demonstrate the difference between a simple @r and (ensure r) in a transaction, define the following ref & function at the REPL: (def r (ref 1)) (defn funk [r] (dosync (let [v (ensure r)] (println v) (Thread/sleep 5000) (println v)))) Now launch it in a separate thread: (.start (Thread. #(funk r))) It'll print a "1" straight away, but you'll have a moment to type in another expression before it proceeds with the second println. So, do this: (dosync (ref-set r 5)) Notice that this blocks until the second println happens, then resets the value of the ref afterwards. With (ensure r) replaced by @r in the definition of funk, the (dosync (ref-set r 5)) would succeed and the funky transaction would retry, thus performing three printlns in total. Thus using ensure may actually make in-transaction side-effects safe at the cost of some lost concurrency. Sincerely, Michał -- 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