On 21 February 2010 13:47, Michał Marczyk <[email protected]> wrote:
> On 21 February 2010 09:37, Michael Wood <[email protected]> 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 <[email protected]>
--
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