Alex Rivera | Logout

How can one create cyclic (and immutable) data structures in Clojure without extra indirection?

Asked 2011-01-02T22:30:07.723
20

I need to represent directed graphs in Clojure. I'd like to represent each node in the graph as an object (probably a record) that includes a field called :edges that is a collection of the nodes that are directly reachable from the current node. Hopefully it goes without saying, but I would like these graphs to be immutable.

I can construct directed acyclic graphs with this approach as long as I do a topological sort and build each graph "from the leaves up".

This approach doesn't work for cyclic graphs, however. The one workaround I can think of is to have a separate collection (probably a map or vector) of all of the edges for an entire graph. The :edges field in each node would then have the key (or index) into the graph's collection of edges. Adding this extra level of indirection works because I can create keys (or indexes) before the things they (will) refer to exist, but it feels like a kludge. Not only do I need to do an extra lookup whenever I want to visit a neighboring node, but I also have to pass around the global edges collection, which feels very clumsy.

I've heard that some Lisps have a way of creating cyclic lists without resorting to mutation functions. Is there a way to create immutable cyclic data structures in Clojure?

Edit
Report

1 Answer

3

I ran into this challenge before and concluded that it isn't possible using truly immutable data structures in Clojure at present.

However you may find one or more of the following options acceptable:

  • Use deftype with ":unsynchronized-mutable" to create a mutable :edges field in each node that you change only once during construction. You can treat it as read-only from then on, with no extra indirection overhead. This approach will probably have the best performance but is a bit of a hack.
  • Use an atom to implement :edges. There is a bit of extra indirection, but I've personally found reading atoms to be extremely efficient.
answered 2011-01-03T18:07:19.917

Your Answer