Clojure последовательности и коллекции
В Лиспе все структуры данных строятся из cons-ячеек, то есть они по сути являются связанными списками, двоичными деревьями или обоими (поправьте меня, если я ошибаюсь). Структуры данных Clojure - это списки, векторы, карты и множества. Clojure включает две инклюзивные абстракции для этих структур данных: коллекции и последовательности. Абстракция последовательности определяет first
, rest
а также cons
операции, где в качестве абстракции коллекции определяют определенные для коллекции операции, такие как conj
а также into
,
Основные функции Clojure, такие как map
а также filter
работает с абстракцией последовательности, но принимает любую структуру данных и выполняет неявное преобразование. Эти функции также ленивы. Означает ли это, что по умолчанию Clojure хранит данные внутри более эффективных структур данных, таких как индексированные массивы, и переключается только на связанные списки по мере необходимости? Как Clojure на самом деле конвертировать коллекции в последовательности? Построена ли последовательность из коллекции с использованием итератора в потоковом режиме или в целом, а затем передана потребителю?
1 ответ
Единственная структура данных в Clojure, которая представляет собой односвязный список, list
лайк:
(list 1 2 3)
Все остальное - эффективная структура данных (т.е. вектор, карта).
Ленивая последовательность (номинально) состоит из текущего значения и рецепта для генерации следующего значения. После вычисления элементы кэшируются и не пересчитываются.
Преобразование коллекции в последовательность - это деталь реализации, которая обычно не важна для конечного пользователя.
Оригинал map
а также filter
функции ленивы, как и многие другие. Тем не менее, этого было достаточно головной боли (непредсказуемого времени реализации), что нетерпеливые / императивные версии mapv
а также filterv
были добавлены к языку.