Clojure: Иммутабельные структуры данных
Как было сказано ранее, структуры данных в Clojure иммутабельны. То есть при изменении коллекции, будет создаваться новая, с измененным элементом. Естественно, возникает вопрос, а насколько это оптимальная операция, на каждое изменение создавать новую коллекцию?
Конечно же, это происходит не совсем так. В Clojure предусмотрен специальный механизм, который отслеживает изменения в структуре данных. Сделано это с помощью ссылок, например, если в векторе меняется один из элементов, то в новом векторе будут ссылки на старые значения, которые не поменялись, плюс новый элемент, который не будет ссылаться ни на что. Это позволяет сократить расходы на память. Однако, если изменить все элементы, тогда полученная структура данных не будет ссылаться на предыдущие элементы и вектор будет совершенно новым.
Однако, в ситуациях, когда иммутабельность начинает сильно влиять на производительность, используются трансдьюсеры (transducers). Подробнее они будут рассмотрены в следующем упражнении.
Задание
Реализуйте функцию, которая разделит вектор на конкретное количество частей.
Примеры:
(partiphify [1] 2)
; => [[1] []]
(partiphify [1 2 3] 3)
; => [[1] [2] [3]]
(partiphify [1 2 3 4 5] 2)
; => [[1 2 3] [4 5]]Полезное
Для любопытных, про трансдьюсеры. Для решения задания можно воспользоваться функцией
partition-all
Clojure: Иммутабельные структуры данных
Как было сказано ранее, структуры данных в Clojure иммутабельны. То есть при изменении коллекции, будет создаваться новая, с измененным элементом. Естественно, возникает вопрос, а насколько это оптимальная операция, на каждое изменение создавать новую коллекцию?
Конечно же, это происходит не совсем так. В Clojure предусмотрен специальный механизм, который отслеживает изменения в структуре данных. Сделано это с помощью ссылок, например, если в векторе меняется один из элементов, то в новом векторе будут ссылки на старые значения, которые не поменялись, плюс новый элемент, который не будет ссылаться ни на что. Это позволяет сократить расходы на память. Однако, если изменить все элементы, тогда полученная структура данных не будет ссылаться на предыдущие элементы и вектор будет совершенно новым.
Однако, в ситуациях, когда иммутабельность начинает сильно влиять на производительность, используются трансдьюсеры (transducers). Подробнее они будут рассмотрены в следующем упражнении.
Задание
Реализуйте функцию, которая разделит вектор на конкретное количество частей.
Примеры:
(partiphify [1] 2)
; => [[1] []]
(partiphify [1 2 3] 3)
; => [[1] [2] [3]]
(partiphify [1 2 3 4 5] 2)
; => [[1 2 3] [4 5]]Полезное
Для любопытных, про трансдьюсеры. Для решения задания можно воспользоваться функцией
partition-all
Ваше упражнение проверяется по этим тестам
(ns immutable-structures-test
(:require [test-helper :refer [assert-solution]]
[index :refer [partiphify]]))
(assert-solution
[[[1] 2] [[1 2 3] 3] [[1 2 3 4 5] 2]]
[[[1] []] [[1] [2] [3]] [[1 2 3] [4 5]]]
partiphify)Решение учителя откроется через:
20:00
