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.

Reply via email to