Подтвердить что ты не робот

Можно ли создавать круговые ссылки в Clojure?

Игнорируя собственные взаимодействия и переходные процессы, можно ли создавать любые структуры данных в Clojure, содержащие прямые циклические ссылки?

Казалось бы, неизменяемые структуры данных могут содержать только ссылки на предыдущие версии. Существуют ли какие-либо API-интерфейсы Clojure, которые могут создать новую структуру данных, которая имеет ссылку на себя?

В схеме есть форма letrec, которая позволяет создавать взаимно рекурсивные структуры, но, насколько я могу судить, Clojure не имеет ничего подобного.

Этот вопрос связан с переносом Clojure в iOS - который не содержит сборку мусора, но имеет подсчет ссылок.

4b9b3361

Ответ 1

Вы можете создать круговую ссылку очень легко, поставив некоторую форму ссылки внутри структуры данных, а затем обновив ссылку, чтобы вернуться к общей структуре.

Тривиальный пример:

(def a [(atom nil)])

(reset! (first a) a)

Это создаст список с одним элементом, который является атомом, который указывает на список.

Ответ 2

В Clojure большинство круговых структур данных будут явно проходить через какой-либо тип ref (например, атом).

Однако вы можете создать круговую последовательность (это несколько оксюморон):

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

И так как Clojure 1.2 с помощью deftype вы можете создавать другие типы данных, которые могут вводить округлость, не используя явно (по крайней мере, от кода пользователя) какой-либо тип ref.