I'm working on some Clojure code that has some circular dependencies between different namespaces and I'm trying to work out the best way of resolving them.
Any thoughts? What is the best way to handle this kind of circular dependency in Clojure?
I remember a number of discussions on namespaces in Clojure -- on the mailing list and elsewhere -- and I have to tell you that the consensus (and, AFAICT, the current orientation of Clojure's design) is that circular dependencies are a design's cry for refactoring. Workarounds might occasionally be possible, but ugly, possibly problematic for performance (if you make things needlessly "dynamic"), not guaranteed to work forever etc.
Now you say that the circular project structure is nice and modular. But, why would you call it that if everything depends on everything...? Also, "every time you have a dependency to resolve" shouldn't be very often if you plan for a tree-like dependency structure ahead of time. And to address your idea of putting some basic protocols and the like in their own namespace, I have to say that many a time I've wished that projects would do precisely that. I find it tremendously helpful to my ability to skim a codebase and get an idea of what kind of abstractions it's working with quickly.
To summarise, my vote goes to refactoring.
I had a similar problem with some gui code, what I ended up doing is,
(defn- frame [args]
((resolve 'project.gui/frame) args))
This allowed me to resolve the call during runtime, this gets called from a menu item in frame so I was 100% sure frame was defined because it was being called from the frame itself, keep in mind that resolve may return nil.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With