tl;dr: In the past I'd always thought of memoization as a way to save the computer work. It hadn't occurred to me that it could also save me work.
I was re-reading "The Joy of Clojure" and came across a gem I'd missed the first time. Listing 14.12 is described as "A function to create or retrieve a unique Agent for a given player name".
(-> (agent )
(set-error-handler! #(println "ERROR: " %1 %2))
;; The above doesn't quite work for me, set-error-handler!
;; doesn't seem to return the agent. Doesn't make the pattern
;; less compelling, though.
The authors comment that this allows you to maintain player-name as an index into a table of agents without having to explicitly manager and lookup agents.
There are two caveats to this approach: 1) player-name must be immutable, and 2) You really need to understand the memoization mechanism. clojure.core/memoize, for instance, will keep a internal map of args/response until the end of time. You could use http://clojure.github.io/core.memoize/ to modify the strategy if you so choose.
The place where I'd try this first is in what I call "micro-logs". Frequently as I'm working, I want to log some data to a side channel, and this pattern saves having to manage this manually and cluttering up my code.
(-> (io/writer file :append true)
:error-handler #(println "ERROR: " %1 %2))))))
"Useful micro-pattern to send off a write to various
files via agents without having to maintain a lookup
table. Symlinks can get you into trouble; at a
minimum they will duplicate the agent."
(let [a (-> (io/file lg)
output (str (str/trim-newline line) "\n")]
(doseq [d all-data]
(microlog lg d)))
Edits: Used io/make-parents instead of File calls. Changed send to send-off, since this is I/O. Cleaned up creation of agent.
Post a Comment