Quite often, there are deeply nested maps in Clojure that correspond to hierarchical trees of objects in object-oriented languages, for example,
{:type :x :name "instance of X" :y {:type :y :name "instance of Y"}}
In fact, it is so widespread that clojure.core provides basic functions such as get-in , assoc-in and update-in to make working with such structures easier.
Of course, this works best when there is a natural hierarchy or ownership relationship between the simulated objects. In the case of circular references, this structure breaks down (if you adhere to persistent data structures) - to understand why, try building a Clojure map that contains itself as a value.
The way I usually saw this is to introduce an indirect layer using atom :
(def x {:type :x, :name "x instance", :y (atom nil)}) (def y {:type :y, :name "y instance", :x (atom nil)}) (set! *print-level* 3) ;; do this in the REPL to avoid stack overflow ;; when printing the results of the following calls (reset! (:yx) y) (reset! (:xy) x)
source share