On 21 February 2010 13:47, Michał Marczyk <michal.marc...@gmail.com> wrote: > 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.
Ah, thanks. > There's no guarantee that the refs won't be changed a split second > after the transaction, of course... 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. That does demonstrate the difference (or a difference), but I don't get 3 printlns. I modified the printlns to distinguish between the two: (defn funk [r] (dosync (let [v @r] (println "Start:" v) (Thread/sleep 5000) (println "End:" v)))) I assume you were expecting something like: user=> (.start (Thread. #(funk r))) Start: 1 nil user=> (dosync (ref-set r 5)) 5 user=> Start: 5 End: 5 ? What I see is: user=> (.start (Thread. #(funk r))) Start: 1 nil user=> (dosync (ref-set r 5)) 5 user=> End: 1 This is with Clojure 1.2.0-master-SNAPSHOT (2855e34106b2cacd4614f2b7e31f1536b4b849bc) > Thus using ensure may actually make in-transaction side-effects safe > at the cost of some lost concurrency. -- Michael Wood <esiot...@gmail.com> -- 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