views:

145

answers:

2

Ignoring native interop and transients, is it possible to create any data structures in Clojure that contain direct circular references ?

It would seem that immutable data structures can only ever contain references to previous versions of themselves. Are there any Clojure APIs that could create a new data structure that has a reference to itself ?

Scheme has the letrec form which allows mutually recursive structures to be created - but, as far as I can tell, Clojure does not have anything similar.

This question is related to porting Clojure to iOS - which does not have garbage collection, but does have reference counting.

+7  A: 

You can create a circular reference very easily by putting some form of reference inside a data structure, then updating the reference to point back to the overall structure.

A trivial example:

(def a [(atom nil)])

(reset! (first a) a)

This will create a list with one element, which is an atom that points back at the list.

mikera
Thanks for the answer. I would only ever use a ref type as a top level object, so I never considered this.
Nick Main
is this a var that points to a list that points to an atom that references a var
Arthur Ulfeldt
@Arther - technically it is a var that points at a vector that contains an atom that points at the vector. i.e. The var itself isn't in the circular loop.
mikera
+2  A: 

In Clojure most circular data structures will explicitely go through a ref type of some kind (eg atom).

However you can create a circular sequence (it's somewhat an oxymoron):

(let [a (atom nil)] (reset! a (lazy-seq (cons 1 @a))))

And now in 1.2 with deftype you can create other datatypes which can introduce circularity without using explicitely (from the usercode at leats) any kind of ref type.

cgrand