Search code examples
clojure

Clojure - is this an appropriate use of an atom?


G'day gurus,

I've written some code that leverages a Java library that makes uses of the visitor pattern. What I'd like is to hide all the messy details of the visitor etc. behind a single Clojure function that takes the input parameter(s) and returns a simple data structure containing all of the state derived by the visitor.

The trick is that there are multiple "visitXXX" callbacks on the Java side and there's no easy way to return state back out of them (Java, being Java, assumes any state that gets built up by the various visitors is stored in instance variables).

What I've done (and which seems to work great, fwiw) is define an atom in a let block, and have each of my visitor functions swap! the atom with an updated value when they're called by the Java visitation code. I then return the deref'ed atom out the end of the main "driver" function, after the Java visitor completes.

My question is: is this an appropriate usage of an atom? If not, is there a more idiomatic way to do this?

If anyone's interested, the code in question is here.

Disclaimer: I'm still a Clojure n00b so that code is probably hideous to the more discerning eye. Comments / feedback / critiques welcome!

Thanks in advance!


Solution

  • Your approach using an atom is fine and looks good and clojurish.

    If you are looking for other approaches as well; since you can split your problem into some code that will produce and answer (your visitor) and some other code that will need the answer when it is available, Clojure's promise and deliver functions may be well suited.

    If you create the promises in the let block, then have the visitor deliver the results to the promise.