Почему immutable это добро?

Когда читаешь умные книги по фнкциональному программированию (в моем случае это была книга по Scala) везде пишут, что immutable это добро. Вроде бы результат налицо: сама собой пропадает проблема с многопоточностью и сайд эффектом к которому может привести mutable. Но также у такого подхода есть свои недостатки (как я понял).
Например есть задача добавить в массив 1000, нет 100000 элементов. True-fp программер скажет что immutable это добро и нам нужно при каждом добавлении создавать новый массив который состоит из элементов старого +1 (что успешно реализовано на уровне ЯП, в двнном случае Scala). Неужели такой подход оправдан с точки зрения ресурсов (памяти в данном случае)? Ведь задача проста, добавлять элементы в массив, на что мы имеем создание 100000 экземпляров массива. Да, я понимаю, что там есть GC который будет убирать за нами, но создание такой достаточно сложной структуры данных как массив (имеется в виду List) будет занимать достаточно большое время.
Что на это скажете?
  • Вопрос задан
  • 658 просмотров
Пригласить эксперта
Ответы на вопрос 3
Andruhon
@Andruhon
Software Developer
Помимо всего прочего, на мой взгляд - вещи, которые меняются - это всегда дополнительная сложность и источник дефектов. Таким образом immutable позволяет уменьшить вышеуказанные риски, порой ценою ресурсов.

Допустим есть класс, в котором есть какое-то поле, которое устанавливается при создании экземпляра этого класса, и читая код - мы можем быть 100% уверенны, что это поле сохранит своё значение при любых условиях для данного экземляра и нам не нужно будет выискивать чтобы ещё с ним могло произойти. Опять таки, можно не заморачиваться с геттерами создал публичную immutable переменную - и данные сразу защищены от записи извне.
Ответ написан
diez_ua
@diez_ua
GlobalLogic, Kyiv, Ukraine
Касаемо immutable массивов – в Scala их нет.

Есть immutable List. Этот List заточен на добавление и удаление элементов в начале списка – head. И если вы делаете map или filter списка – новый список формируется в том же "оптимальном" порядке.

В таком случае никакого перерасхода памяти и нагрузки на GC по сравнению с Java LinkedList нет: при добавлении элемента создается НОВЫЙ объект List со ссылкой на новый элемент (head) и ссылкой на прежний список (tail). Старые листы в деле. Каждый новый лист – объект из всего двух референсов.
Ответ написан
Комментировать
laughedelic
@laughedelic
Неужели такой подход оправдан с точки зрения ресурсов (памяти в данном случае)?


В функциональных языках, в том числе в Scala используются т.н. persistent data structures. В памяти хранятся ссылки на предыдущие состояния структуры данных и изменения. Это имеет смысл в сочетании с упомянутой вами сборкой мусора. Разумеется можно просто копировать всё, но на деле так никто не делает. Поскольку в ФП очень много используются структуры типа списков и деревьев, для них это легко реализовать эффективно.
Рекомендую почитать (англ.) википедию по ссылке выше или вот эту вики на русском.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Войти через центр авторизации
Похожие вопросы