Хабр Курсы для всех
РЕКЛАМА
Практикум, Хекслет, SkyPro, авторские курсы — собрали всех и попросили скидки. Осталось выбрать!
readonly List<int> Values делать не следует, по очевидным причинам.Элементарно. При параллельном доступе к иммутабельному объекту синхронизации по записи нет в силу отсутствия записи, синхронизация по чтению не нужна в силу отсутствия изменений.Как вы собираетесь использовать велосипед вместо автомобиля, расстояния то большие?
Далее — если у вас есть иммутабельный объект и нужен новый, отличающийся несколькими изменениями, то опять-таки никакого копирования не нужно: достаточно в новом объекте иметь ссылку на старый и набор изменений.Ага, особенно хорошо это можно проделать для графа.
Попробуйте передать мутабельный объект сложному (или просто не вашему) методу, а потом воспользоваться его прежним состоянием. «Защитное» копирование начнет плодиться со страшной силой.
Правда? И как эта оболочка сохранит объект от изменений, сделанных при доступе помимо нее?Я же написал — что в ряде случаев. Например для массива примитивных типов. Если не уверен вдруг — можно иногда сделать дешевую обертку. А вообще недекларируемое изменение объектов-параметров — это как раз зло в первую очередь. И опять же — ну избавились вы от одной проблемы введя везде immutable и получили проблемы в 10 других местах.
Пока не видел здесь никого, кто хотя бы упоминал тезис «наш код — иммутабельный»Да? А это что тогда? Конечно другими словами но это самое настоящее обобщение вида «иммутабельное — лучше».
Потому что иммутабельное гораздо проще в эксплуатации (не надо делать копию на каждый чих, нет проблем с параллельным доступом, можно спокойно передавать куда угодно без риска испортить.
А что если я хочу использовать текущее состояние словаря для объемных расчетов?Что? Как? Вам его надо обновлять.
Что именно, для чего и куда записывать? Вы всегда подменяете тезис во время дискуссии?
public IEnumerable<int> Convert(IEnumerable<string> strings)
{
foreach(string s in strings)
{
yield return _mySharedMutableConcurrentDictionary.MyGetOrAdd(s, () => Interlocked.Increment(ref _mySharedMutableInt));
}
}PS: Подумайте, стоит ли начинать разговор с хамства,Я критиковал ваш пост, а не вас лично. Чушь все время от времени пишут.
public sealed class Mutable
{
public Type1 PropertyA { get; set; }
public Type2 PropertyB { get; set; }
}
public sealed class Immutable
{
public Immutable(Type1 valueA, Type2 valueB)
{
fieldA = valueA;
fieldB = valueB;
}
public Type1 PropertyA => fieldA;
public Type2 PropertyB => fieldB;
private readonly Type1 fieldA;
private readonly Type2 fieldB;
}
Массив примитивных типов вполне себе изменяем, если откуда-то еще, кроме оболочки к нему есть доступ как к массиву. Совсем плохо, что оболочка не может это контролировать.Еще раз перечитайте. Такая оболочка — простой способ защитить некоторые типы от условного «незнакомого» кода. Это такой костыль который немного заменяет отсутствие const.
public sealed class Immutable
{
public Immutable(Type1 valueA, Type2 valueB)
{
PropertyA = valueA;
PropertyB = valueB;
}
public Type1 PropertyA { get; }
public Type2 PropertyB { get; }
}
class Unit {
int Id;
string Name;
}
// пусть val - неизменяемая ссылка
val unit = new Unit {Id = 42, Name = "test"};
unit.Id = 13;
void Spoil(Unit unit)
{
unit.Id = 13;
}
что обычно на любую реализацию с изменяемыми объектами найдётся реализация с неизменяемымиЯ выше показал что не на любую.
А по моему опыту — недостаточно.Ваш опыт идет вразрез с опытом индустрии.
Согласен. Тут только язык переделывать. Но всё-же, это сложнее, чем вызвать setter.При чем тут setter? Я же написал — что в данном случае надо писать const метод, тогда будет видно что этот метод не изменяет значения.
и. Поясню. Вы приводили в пример запись из 10 потоков в ConcurrentDictionary, но такой алгоритм — это скорее всего решение какой-то другой задачиКакой задачи? Я привел описание задачи и ее решение.
Из вредности я тоже могу придумать задачу, которую с mutable значениями будет решать очень геморройно, но зачем?Так я не отрицаю что такие задачи есть (не то чтобы геморойно, просто в специфичных задачах плюсы перевешивают минусы и без immutable больше вероятность ошибок). Я говорю только то что далеко не все задачи — такие, многие задачи гораздо лучше решаются с mutable типами.
void Spoil(Unit unit)
{
unit.Id = 13;
}
Это очень сильное обязательство, особенно если метод вызывает другие методы, у которых есть прямой прямой или косвенный доступ к содержимому параметра.А как он может вызвать другие методы которые параметр изменяют?
Что мешает после вызова изменить переданный ранее объект и внезапно обрушить задачу в другом потоке, которую создал тот самый злосчастный метод?Самый очевидный подход — это понимать разницу между ссылкой и указателем, если метод продлевает время жизни параметра до момента после момента завершения метода — он принимает указатель, иначе — ссылку.
Это взаимоисключающие параграфы, если нет дополнительных условий.Я же написал выше:
K-арное (K — фиксировано) дерево.
Вам, в свою очередь, предоставляю право рассказать, почему у Erlang'а с горизонтальной масштабируемость все намного лучше чем, к примеру, у Python'а. Тем более что Erlang несет на себе страшный оверхед от иммутабельности.Я вам выше привел пример задачи. Задача у меня заняла 1 строчку собственно логики + объявление метода, поэтому имею полное моральное право фразу вида «По какой ставке вы готовы платить мне за эту работу?» в ответ на подобную задачу засчитать за признание собственной неправоты.
Кстати, тема исходной статьи — упрощенный синтаксис для описания простых иммутабельных сущностей.Я отвечал не на исходную статью а на выпад «Потому что иммутабельное гораздо проще в эксплуатации» и собственно в продолжение соответствющей дискуссии.
Зачем ВСЕ делать иммутабельным?Я не знаю, вы обобщили «Потому что иммутабельное гораздо проще в эксплуатации», потом опять обобщение «Да и зачастую куда дешевле купить новую железку, чем тратить кучу времени на отлов кучи багов, которую за собой принесет использование не иммутабельных типов.» Вот у авторов этих цитат я и спрашиваю — зачем все делать иммутабельным?
В энтерпрайзе в первую очередь важна простота кода, а не производительность. Да и зачастую куда дешевле купить новую железку, чем тратить кучу времени на отлов кучи багов, которую за собой принесет использование не иммутабельных типов.Камент не ваш, но в этой ветке. Скажите, что тут вырвано из контекста? Тут абсолютно четко написано что иммутабельно == лучше, и что это в общем, а не в разрезе статьи. Как бы на хабре часто ветки комментариев не относятся к содержимому статьи.
Потому что иммутабельное гораздо проще в эксплуатации (не надо делать копию на каждый чих, нет проблем с параллельным доступом, можно спокойно передавать куда угодно без риска испортить.Это исключительно о том что „immutable — добро“. А дальше сетование на то что это добро сейчас делать тяжелее.
Когда нет сил ждать Record'ы