Это не так, что трудно иметь ссылки на объекты в ближайшем будущем;но, как правило, эти ссылки неизменны.Это неизменность, которая делает двусвязный список невозможным, потому что в отличие от односвязного списка, вы не можете изменить какую-либо его часть без создания где-либо мутации.
Чтобы увидеть это, предположим, у меня есть односвязный список,
a -> b -> c
и предположим, что я хочу изменить голову.Я могу сделать это, изменив весь список.Я создаю новый список, создавая новое значение для значения заголовка, и повторно использую хвост:
a'-> b -> c
Но двусвязные списки невозможны.Поэтому в clojure и других функциональных языках мы иногда используем zipper в таких ситуациях.
Теперь предположим, что вам действительно нужны изменяемые ссылки в Clojure - как это сделать?Ну, в зависимости от того, какая семантика параллелизма вам нужна, у clojure есть переменные , ссылки , атомы и т. Д.
Также с deftype , вы можете создавать объекты, которые имеют изменяемые поля, и эти изменяемые поля могут содержать ссылки на другие объекты.Вы также можете использовать необработанные Java-массивы в clojure для этой же цели.
Будет ли ваша база данных базой данных в памяти или базой данных на диске?Если на диске, я думаю, что проблема свиста указателя сложнее, чем наличие изменяемых ссылок.
Возвращаясь к вопросу о функциональных структурах данных, я считаю, что возможносоздавать B-деревья, которые имеют чисто функциональную семантику.Первая подсказка заключается в том, что это дерево, а деревья - это хлебное масло и мясо функциональных структур данных.Во-вторых, обратите внимание, что существуют базы данных, которые работают только в виде дополнений - например, couchDB.Преимущество в том, что база данных - это собственный журнал, в некотором смысле.Чтобы получить более полное представление о стоимости и преимуществах этого подхода, вы можете посмотреть презентацию Славы Ахмечета .Его компания, RethinkDB, в конечном итоге выбрала своего рода гибридный подход, IIRC.