Indeed you're right, I was confused. The dosync call was a naive attempt to avoid the CAS operation you were worried about earlier. I suppose another option would be to use compare-and-set! with a lazy seq.
(compare-and-set! cache-atom (dissoc @cache-atom k) (assoc @cache-atom k (lazy-seq (cons (expensive k) '())))) (first (@cache-atom k)) On Monday, September 1, 2014 7:10:52 PM UTC+10, Colin Fleming wrote: > > Hi Beau, > > I've not used the STM stuff at all, but my understanding is that dosync is > intended for co-ordinated updates to refs, and has no effect on atoms. It's > really intended for co-ordinating updates to multiple refs rather than as a > synchronisation primitive on a single entity. I might be wrong though, as I > say I've never used it. > > Cheers, > Colin > > > On 31 August 2014 00:58, Beau Fabry <imf...@gmail.com <javascript:>> > wrote: > >> I must be missing something, because this is too simple? >> >> (defn get-maybe-cached [cache key] >> (dosync >> (if-let [v (get @cache key)] >> v >> (do >> (reset! cache (assoc @cache key (calculate key))) >> (get @cache key))))) >> >> >> On Saturday, August 30, 2014 3:27:05 PM UTC+10, Colin Fleming wrote: >>> >>> Hi all, >>> >>> I want to use a map to cache values based on a key. I'm planning to use >>> an atom for this. My basic operation is "give me the value for this key" - >>> if the value exists in the map then that value should be returned, >>> otherwise a new value should be calculated, inserted in the map and then >>> returned. My plan is to implement something like the following: >>> >>> >>> (defn ensure [cache key] (if (contains? cache key) cache (assoc >>> cache key (calc-value key))))(let [value (get (swap! cache ensure key) >>> key)] ... do my thing with value ...) >>> >>> >>> So 'ensure' ensures that the cache contains the value for key, the swap! >>> operation returns the cache with the value and then I get it out. This >>> works but feels a little clumsy, is there a better way to do this? >>> >>> Also, looking at the Atom source code, I see that this will cause a CAS >>> operation even if the value returned from swap! is identical to the >>> original value. It seems like a reasonable optimisation would be to check >>> if the values are identical and not update if so - is there a reason this >>> might not be a good idea? >>> >>> Thanks, >>> Colin >>> >> -- >> You received this message because you are subscribed to the Google >> Groups "Clojure" group. >> To post to this group, send email to clo...@googlegroups.com >> <javascript:> >> Note that posts from new members are moderated - please be patient with >> your first post. >> To unsubscribe from this group, send email to >> clojure+u...@googlegroups.com <javascript:> >> 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+u...@googlegroups.com <javascript:>. >> For more options, visit https://groups.google.com/d/optout. >> > > -- 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.