Из дискуссии с
victorgr в посте
http://jakobz.livejournal.com/258478.html > Да, но альтернатива - это вот так руками обеспечивать иммутабельность.
В этом месте я, пожалуй, немного порассуждаю. Почему иммутабельность стала безусловным благом? Неужели разработчики готовы платить любую цену за нее?
При выборе подхода я отвечаю себе на несколько вопросов:
1. Какие проблемы он решает?
2. Какие проблемы он создает?
3. Что еще может решить эти же проблемы? (это хвостовой вызов :)
Итак, по порядку.
1. Иммутабельность призвана решить несколько проблем:
a) Гарантировать в конкурентной среде что объект не будет ошибочно изменен другой рутиной. Это нужно для того, чтобы всегда работать с целостными данными.
б) За счет постоянного копирования легко воспроизвести предыдущее состояние, а значит сравнительность просто реализовать отмену.
в) Вкупе с vdom можно уменьшить количество отрисовок, так как быстро вычисляется equals для вложенных объектов (если реализован structural sharing, конечно).
2. Иммутабельность создает несколько не менее неприятных проблем:
а) Очень сложно работать с графовыми структурами. Если предметка их требует, то швах.
б) Требуются преобразования на границах между подсистемами. Seamless-immutable снимает эту проблему только наполовину - входы в "иммутабельное" пространство точно так же выделяются явно.
в) Проблемы с асинхронностью решаются неполностью - ничего не мешает применить изменения к корневому объекту в неправильном порядке.
г) Сложно использовать не Javascript. Например, для поддержки TypeScript придется для каждой структуры делать дополнительную обертку с преобразованием. Даже если мы решаем этот вопрос кодогенерацией (препроцессорами или сниппетами), этот код все равно придется читать, когда что-то пойдет не так.
д) С отменой все хорошо до первого сайдэффекта. В SPA с вебсокетами сайдэффектов чуть ли не больше, чем в SPA со старым добрым ajax.
Отдельным пунктом я бы добавил популярные библиотеки redux и flux управления иммутабельным состоянием. При всех положительных свойствах количество неявного взаимодействия при росте приложения становится очень непросто поддерживать. Ну и читать код с кучей неявных вызовов - сомнительное удовольствие, пусть у тебя трижды таймтревел.
Альтернативой могут быть библиотеки с observable структурами, например, mobx или nested types. Там эти же проблемы решаются по-другому, со своими плюсами и минусами.
Резюмируя:
Мне нравится иммутабельность, но я стараюсь выбирать подход исходя из контекста. Если моя текущая команда, сроки и требования позволяют мне эффективно (в смысле бизнеса) использовать языки, которые поддерживают ее из коробки (ClojureScript, Elm, Erlang или что угодно еще), то я с удовольствием буду пользоваться ее преимуществами. Если я вынужден работать с платформой, в которую это притягивается с усилием - я подумаю о компромиссе и выберу то, что проще в долгосрочной перспективе. По моему мнению, насильное втаскивание иммутабельности в js того не стоит.