On Aug 25, 3:33 pm, "Shawn Hoover" <[EMAIL PROTECTED]> wrote:
> On Mon, Aug 25, 2008 at 11:57 AM, Rich Hickey <[EMAIL PROTECTED]> wrote:
>
> > (def hits (ref 0))
> > (def cache (ref {:n nil :factors nil}))
> > (def cache-hits (ref 0))
>
> > (defn cached-factor [n]
> >   (dosync (commute hits inc))
> >  (let [cached @cache]
> >    (if (= n (cached :n))
> >      (dosync (commute cache-hits inc)
> >        (cached :factors))
> >       (let [factors (factor n)]
> >        (dosync
> >          (commute cache (fn [_] {:n n :factors factors})))
> >        factors))))
>
> > The ref-sets were needed in your example, but with a composite cache,
> > you can use the commute trick above (commute with a fn that ignores
> > its arg) to get last-one-in-wins, since this is just a last-value-only
> > cache.
>
> Is there a stylistic or correctness advantage to using commute over ref-set
> on the composite cache? As in:
> (dosync (ref-set cache {:n n :factors factors}))
>

ref-set is more 'correct' in that the new value is not a function of
the old, and I recommend it over what I showed when that is the
general case. In this specific case, the wholesale replacement was
last-one-in-wins with no in-transaction dependent data (i.e. the basis
for the new state was not derived from refs in the transaction, so
commute was possible. commute is always just an optimization vs.
alter, and alter is preferred over ref-set when the new state is a
function of the old, which is normally the case.

Rich

--~--~---------~--~----~------------~-------~--~----~
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
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
-~----------~----~----~----~------~----~------~--~---

Reply via email to