On Tue, Mar 20, 2012 at 11:16 AM, Tom Krestle <[email protected]> wrote:
> Greetings,
>
> I've stumbled across the following problem, which I believe is common and
> should have some sort of generic solution. Imagine I have
>
> ... ;; code inside defn
> ;; I extract some information out of my atom in closure:
> (swap! my-atom
> (fn [val]
> (let [extracted-info1 (extract-something-from val)
> extracted-info2 (extract-something-else-from val)]
> ;; update the atom
> (-> val
> (assoc ...) (assoc))))) ;; out of swap!
>
> ;; still code inside defn
> ;; now, here I need to use those extracted-info1, extracted-info2 that I got
> out of atom inside swap! operation
> ;; What would be the common way to pass that information here? Using vals
> doesn't sound right.
>
> Have a beer!
> Tom
The ugly way, as you noted, is to change the atom from some-map to
[some-map extracted-info-from-last-swap].
A less ugly way might be
(let [ei (atom nil)]
(swap! my-atom
...
(reset! ei extracted-info1)
...)
(do-things-with ei))
If the swap! is retried, the ei atom will be reset! more than once,
but it will after the swap! contain the extracted-info1 from the
successful swap! of my-atom.
The most functional way would be to see if you couldn't do the work
with ei *inside* the closure. However, if it's expensive or
side-effecty that doesn't play nice with swap! retrying. In that
instance, you might want to think of replacing my-atom with my-ref and
doing something like
(dosync
(alter my-ref
...
(send-off ei-agent ei-do-things-func extracted-info1)
...))
Agent sends are held until a transaction commits, so the
ei-do-things-func will be called only once for each transaction on
my-ref.
--
You received this message because you are subscribed to the Google
Groups "Clojure" group.
To post to this group, send email to [email protected]
Note that posts from new members are moderated - please be patient with your
first post.
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