Hi Andy,

Just my two cents here, but I don't think memoize makes sense here myself 
due to this not being referentially transparent, and I think Andrey's 
comment on delays makes more sense to me.  You could do something like this:

(def conf (atom (delay (read-and-expensively-parse "somefile.xml"))))

(defn config []
  @(deref conf))

(defn reload-conf! []
  (reset! conf (delay (read-and-expensively-parse "somefile.xml")))

This would ensure that there's a valid delay in there for the first time 
anyone hits config, and still let you reload by replacing the delay in the 
conf atom with a new one. 

Also, just FYI, for this code:

(defn config []
  (if (nil? @conf) (reset! conf (read-and-expensively-parse 
"somefile.xml")) @conf))

There's a danger here in that the time between the first @conf and the 
reset! is not protected, i.e. this is not an atomic operation.  So if n 
threads hit config at the same time, it's entirely possible that n calls to 
read-and-expensively-parse could happen.  I don't know if that's a 
possibility to have multiple callers to config with the codebase you have, 
but I think that general code pattern is one to be careful about.  

Cheers!
steven

On Tuesday, December 9, 2014 12:08:25 PM UTC-5, Andy Dwelly wrote:
>
> Looking through my recent work I see that a number of atoms, swap! and 
> reset! calls have snuck into my work, usually when there's an expensive 
> operation like reading and parsing a large file or connecting to a 
> database. I find I'm doing things like
>
> (def conf (atom nil))
>
> (defn config []
>   (if (nil? @conf) (reset! conf (read-and-expensively-parse 
> "somefile.xml")) @conf))
>
> So that the first time (config) is called it will do the operation, but 
> future attempts will simply deref the atom.
>
> Recent discussions here alerted me to memoize which will do this without 
> the atom, but the documentation mentions that the functions that are 
> memoized should be referentially transparent. Although I'm pretty sure that 
> while my server is running, the config will not change - it can't be 
> guaranteed in a formal sense. Reading a file or connecting to an external 
> process is doing io of course, in theory someone could change the file 
> while my back was turned.
>
> Questions: if I was prepared to live with the consequences of having to 
> restart the server if the conf file had been changed, would it be more 
> idiomatic to use use memoize to avoid mutating state?
> If I really had to change a conf file while the server was running, is 
> there any way a memoized function could have it's cache cleared? I suspect 
> the answer to that one is no - but you never know....
>
>

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