clojure circular-reference

¿Es posible crear referencias circulares en Clojure?



circular-reference (2)

Ignorando interoperabilidad y transitorios nativos, ¿es posible crear cualquier estructura de datos en Clojure que contenga referencias circulares directas?

Parecería que las estructuras de datos inmutables solo pueden contener referencias a versiones anteriores de ellos mismos. ¿Hay alguna API Clojure que pueda crear una nueva estructura de datos que tenga una referencia a sí misma?

Scheme tiene la forma letrec que permite crear estructuras mutuamente recursivas, pero, hasta donde puedo decir, Clojure no tiene nada similar.

Esta pregunta está relacionada con la migración de Clojure a iOS, que no tiene recolección de basura, pero sí cuenta de referencia.


Puede crear una referencia circular muy fácilmente colocando alguna forma de referencia dentro de una estructura de datos, y luego actualizando la referencia para señalar la estructura general.

Un ejemplo trivial:

(def a [(atom nil)]) (reset! (first a) a)

Esto creará una lista con un elemento, que es un átomo que apunta hacia atrás en la lista.


En Clojure, la mayoría de las estructuras de datos circulares atravesarán explícitamente un tipo de ref de algún tipo (por ejemplo, átomo).

Sin embargo, puedes crear una secuencia circular (es algo así como un oxímoron):

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

Y desde Clojure 1.2 con deftype puede crear otros tipos de datos que pueden introducir circularidad sin utilizar explícitamente (desde el código de usuario al menos) cualquier tipo de tipo de referencia.