Having learned a little more about refs and transactions from M. Fogus and
C. Houser The Joy of Clojure, Second Editionhttp://www.manning.com/fogus2/,
I altered the stress-ref function from 10.2.4. Using Clojure 1.5.1:
(defn stress-ref [r]
(let [slow-tries (atom 0)]
(future
(dosync
(swap! slow-tries inc)
(Thread/sleep 200)
@r)
(println (format r is: %s, meta: %s, history: %d, after: %d tries
@r (meta @r) (.getHistoryCount r) @slow-tries)))
(dotimes [i 500]
(Thread/sleep 10)
(dosync (alter r #(let [r0 (first %)]
(condp = r0
:identical %
:= (with-meta % {:mkw (inc (:mkw (meta
%)))})
(with-meta [(inc r0)] {:mkw (inc (:mkw (meta
%)))}))
:done))
Using this function in the following ways
user= (stress-ref (ref (with-meta [:identical] {:mkw 0})))
:done
r is: [:identical], meta: {:mkw 0}, history: 10, after: 26 tries
user= (stress-ref (ref (with-meta [:=] {:mkw 0})))
:done
r is: [:=], meta: {:mkw 500}, history: 10, after: 26 tries
user= (stress-ref (ref (with-meta [0] {:mkw 0})))
:done
r is: [500], meta: {:mkw 500}, history: 10, after: 26 tries
From these results I infer that a snapshot is pushed to history whenever
alter (et al) are used. Any efficiencies need to be implemented in the
Clojure code, eg.
(defn stress-ref-equal [r]
(let [slow-tries (atom 0)]
(future
(dosync
(swap! slow-tries inc)
(Thread/sleep 200)
@r)
(println (format r is: %s, meta: %s, history: %d, after: %d tries
@r (meta @r) (.getHistoryCount r) @slow-tries)))
(dotimes [i 500]
(Thread/sleep 10)
(dosync (let [r0 (first @r)]
(condp = r0
:identical (ensure r)
:= (ensure r)
(alter r #(with-meta [(inc r0)] {:mkw (inc (:mkw (meta
%)))}))
:done))
user= (stress-ref-equal (ref (with-meta [:identical] {:mkw 0})))
r is: [:identical], meta: {:mkw 0}, history: 0, after: 1 tries
:done
user= (stress-ref-equal (ref (with-meta [:=] {:mkw 0})))
r is: [:=], meta: {:mkw 0}, history: 0, after: 1 tries
:done
user= (stress-ref-equal (ref (with-meta [0] {:mkw 0})))
:done
r is: [500], meta: {:mkw 500}, history: 10, after: 26 tries
The documentation at Refs and Transactions http://clojure.org/refs only
refers to change without defining what is meant by change. Given the
admonition not to rely on inferences as made above, what's a coder to do?
Future optimization of refs and transactions may break the code.
As a beginner, I can't tell if I'm just confused, or if this is actually
confusing.
--
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
---
You received this message because you are subscribed to the Google Groups
Clojure group.
To unsubscribe from this group and stop receiving emails from it, send an email
to clojure+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.