Having learned a little more about refs and transactions from M. Fogus and 
C. Houser "The Joy of Clojure, Second Edition"<http://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.

Reply via email to