I think I'm right. This is a program that demonstrates what I was thinking o:
;; Program begins. (defn traverse [f dat] (vec (map #(f %) dat))) (def data (traverse ref (take 10 (iterate inc 0)))) (-> (fn [] (dosync (loop [i 0 data data] (when (seq data) (Thread/sleep 1000) (println (str ">>> " i ": " @(first data))) (recur (+ i 1) (next data)))))) Thread. .start) (Thread/sleep 1500) (dosync (traverse (fn [ref] (alter ref inc)) data)) (Thread/sleep 1000) ;; This one extra sleep forces the "main" thread sleeping for one ;; second. Due to some reason I don't know for now, when `dosync' ;; retries, the first sleep will be interrupted. (Thread/sleep 1000) (dosync (traverse (fn [ref] (alter ref inc)) data)) (traverse #(println (str "--- " @%)) data) ;; Program ends here. The result is >>> 0: 0 >>> 0: 1 --- 2 --- 3 --- 4 --- 5 --- 6 --- 7 --- 8 --- 9 --- 10 --- 11 >>> 1: 2 >>> 0: 2 >>> 1: 3 >>> 2: 4 >>> 3: 5 >>> 4: 6 >>> 5: 7 >>> 6: 8 >>> 7: 9 >>> 8: 10 >>> 9: 11 Meaning the `dosync' form in the thread is retried twice, due to the two passes of changing of the values in `data'. So using `dosync' to surround the whole data structure is the best way to go. Best regards, Guanpeng Xu On Tue, Jan 31, 2012 at 12:00 PM, Herbert Euler <herberteu...@gmail.com>wrote: > Hmm, I didn't read the definition of `board-map' carefully. It seems the > second form > > (dosync (board-map deref board)) > > is the best among the three, as it views `board' as a whole. The other > two might have the potential problem of printing incoordinated values of > entries in `board', i.e. the entries of `board' might change during the > iteration in the `map' form. Am I right? > > Thanks, > Guanpeng Xu > > On Tue, Jan 31, 2012 at 11:46 AM, Guanpeng Xu <herberteu...@gmail.com>wrote: > >> Hi all, >> >> In section 11.2.1 of the book /The Joy of Clojure/, the author shows >> the effect of >> `dosync' by starting 100 threads and then watching the value of a Ref: >> >> (go make-move 100 100) >> (board-map #(dosync (deref %)) board) >> >> Here, the first `go' form starts 100 threads, their effect is >> modifying `board' using >> `dosync' and `alter'. `board-map' is defined as >> >> (defn board-map [f bd] >> (vec (map #(vec (for [s %] (f s))) bd))) >> >> I don't quite understand the use of `dosync' in the second `board-map' >> form. In >> my testing, the following three seems identical: >> >> (board-map #(dosync (deref %) board) >> (dosync (board-map deref board)) ;; Should be the same as above >> (board-map deref board) ;; Without `dosync' at all >> >> The docstring of `deref' says "Within a transaction, returns the in- >> transaction-value >> of ref, else returns the most-recently-committed value of ref." So >> the above three >> forms are all the same, right? Or is there any difference between >> them? >> >> Thanks in advance, >> Guanpeng Xu > > > -- 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