Re[9]: Только мне в дотнете не хватает неизменяемого массива
От: Sinix  
Дата: 01.02.11 01:00
Оценка:
Здравствуйте, samius, Вы писали:

S>Ну вот, R/O collection... А что эта коллекция говорит об изменяемости данных коллекции?

То же самое, что и гипотетический R/O-массив. Заполнять его копированием будет _очень_ дорого, особенно в сравнении с сэкономленными спичками. К тому же, если ваш код пытается изменять выданные наружу данные, иммутабельность массивов — меньая из ваших проблем

Если хочется warning-ов при компиляции — есть FxCop|CodeAnalysis, написать правило, проверяющее инстанциирование R/O коллекции неизменяемым впоследствии массивом не так уж и сложно.
Re[5]: Только мне в дотнете не хватает неизменяемого массива
От: Sinix  
Дата: 01.02.11 01:49
Оценка:
Здравствуйте, VladD2, Вы писали:

Ок, принято Ещё чуть помучаю вопросами, чтобы указать на узкие (с моей точки зрения) места.

S>>Как описывать многомерные массивы?


VD>Эх. Это, на мой взгляд еще одна ошибка дизайна дотнета. Не надо было делать многомерные массивы встроенными типами. Их надо было реализовать как классы.


А как? Генерить кучу классов аля Array2D, Array3D, ... Array18D ...? Кошмарно ведь выглядит.
*Если честно, мне многомерные массивы в продакшн-коде пока использовать не пришлось, поэтому спорить насчёт их сомнительной полезности как-то не с руки Есть — и хорошо.

VD>Ну, да тут ничего не поделаешь уже. Но их поддержка не должна повлиять в данном случае. Размерность массива — это еще один атрибут массива. На его неизменяемость или типизацию не влияющий.

Увы, есть свойства — индексаторы. Для каждой размерности — свои.



S>>Каст от одного к другому — копированием? Тогда вызов метода, принимающего ImmutableArray будет неэффективным.
S>>Обёрткой?
VD>Почему? Нет, конечно. Базовый тип просто не должен содержать реализации.
Эмм, я неправильно сформулировал вопрос.
int[] data = { 1, 2, 3 };
ImmutableArray<int> roData = new ImmutableArray<int> (data); // Вот тут - произойдёт копирование, или нет?


S>>Наконец, что делать, если значения в массиве — mutable?

VD>Если же в массиве лежит ссылка на объект содержащий изменяемые поля, то их можно будет по прежнему изменять, так как это память уже не принадлежит массиву.
Именно. И какая польза от immutable-массивов, если в половине случаев эту самую иммутабельность не обеспечить? Они тут же превращаются из главной фичи в приятную побочную мелочь. А только ради приятной мелочёвки никто рантайм корёжить не будет.



VD>>>3. Ввел бы концепцию "хвостовых массивов".
S>>Что это даст и в каких сценариях будет полезно? В 99.(9)% доступ к массиву осуществляется не напрямую, так что выигрыш будет съеден стоимостью вызова ацессора.

VD>Выигрыш в том, что объект и массив размещаются в единой области памяти. Не нужно тратить 12 байт на второй объект, и не нужно делать ссылки на него. Массив просто находится по определенному смещению в теле объекта.

Ок, понятно. Только почему 12? Во всех источниках — 8:
http://msdn.microsoft.com/en-us/magazine/cc163791.aspx#S7
http://stackoverflow.com/questions/3815227/understanding-clr-object-size-between-32-bit-vs-64-bit
http://netinverse.com/devblogs/debugging/advanced-net-debugging-clr-objects-internal-structure/626/

VD>Затем чтобы:

VD>1) небыло хардкода в рантайме;
VD>2) прикладные программисты могли бы создавать контейнерные типы не менее эффективне нежели те, что захаркодены в рантайме.

А смысл? Весь выигрыш — потеря 8 байт на контейнер. Харкод в рантайме будет в любом случае, иначе не будет дешёвой аллокации.

VD>То что сделано в донтете сегодня — это просто кривой хардкодинг двух типов в рантайме и наплевательское отношение к остальным типам.

Можно называть кривым и идиотским абсолютно всё, что выглядит непонятным. Вот так
Автор:
Дата: 31.01.11
(и ниже по ветке) это выглядит со стороны. Поэтому я обычно предпочитаю разбираться в первопричинах.



VD>Почему System.Strung эффективнее чем List<T>?
Потому что string — встроенный тип и разработчики не поленились оптимизировать под него рантайм.
Чуть подробней — http://www.codeproject.com/KB/dotnet/strings.aspx

VD>Никакая трассировка не нужна, так как каждый вызов такого метода будет создавать новую копию массива. Генерировать исключения тоже не надо, так как корректность доступа можно проверить статически во время джит-компиляции или верификации.

Тогда вся дискуссия о "эффективности контейнеров" сразу теряет смысл — стоимость копирования убивает все нанооптимизации на корню



S>>А сколько придётся вводить для многомерных массивов/массивов с ненулевой индексацией?
VD>Массивов с индексом отличным от нуля в дотнете и так нет.
      Array data = Array.CreateInstance(typeof(int), new[] { 1 }, new[] { 2 }); // длина, нижняя граница.
      data.SetValue(123, 2);

      Console.WriteLine(data.GetValue(2));
      Console.WriteLine(data.Length);


VD>Для эмуляции можно использовать классы. С многомерными массивами никаких проблем не будет. Ты их опять же сам придумал. Вся разница многомерных массивов заключается только в наличии у них метаатрибута "размерность". В остальном это такой же непрерывный участок памяти.


Индексаторы А также куча других оптимизаций.
Re[10]: Только мне в дотнете не хватает неизменяемого массив
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.02.11 06:02
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, samius, Вы писали:


S>>Ну вот, R/O collection... А что эта коллекция говорит об изменяемости данных коллекции?

S>То же самое, что и гипотетический R/O-массив.
Отнюдь не то же самое. В одном случае данные могут быть изменены, в другом — нет. С неизменяемыми массивами можно кэшировать результат обработки, с ReadOnlyCollection<T> — требуется пересчитывать.

S>Заполнять его копированием будет _очень_ дорого, особенно в сравнении с сэкономленными спичками.

Не сильно дороже чем заполнять копированием строки

S>К тому же, если ваш код пытается изменять выданные наружу данные, иммутабельность массивов — меньая из ваших проблем

Мой код (и не только) пытается следовать гайдлайнам и защищать внутренние данные от модификации извне. Проблема тут обратная. Если данные не выглядят защищенными, то почему бы не воспользоваться этим по месту и не изменить их при необходимости (Вы же не копируете каждый массив, созданный не вами?). Ой, изменили, а там где-то что-то сломалось...
Т.е. проблема не в том что кто-то пытается изменять данные, а в том что по данным (по типу) не видно, можно ли их изменять, изменятся ли они "сами" со временем, как в случае со строкой.

S>Если хочется warning-ов при компиляции — есть FxCop|CodeAnalysis, написать правило, проверяющее инстанциирование R/O коллекции неизменяемым впоследствии массивом не так уж и сложно.

Вообще не так уж и сложно обеспечить себя вполне MyИммутабельнымМассивом, MyWarning-ами, MyПравилами. Но речь идет о штуке из коробки, которая может быть использована всеми, а не только мной.
Re[11]: Только мне в дотнете не хватает неизменяемого массив
От: Sinix  
Дата: 01.02.11 06:36
Оценка:
Здравствуйте, samius, Вы писали:

S>>Заполнять его копированием будет _очень_ дорого, особенно в сравнении с сэкономленными спичками.

S>Не сильно дороже чем заполнять копированием строки

Embedded-cтроки очень эффективно инициализируются, а напрямую ими манипулируют относительно редко. С массивами, напротив, большинство сценариев — на заполнение/изменение/передачу буфера. Например, поблочное копирование с одного потока в другой при вашем подходе не взлетит.

S>>К тому же, если ваш код пытается изменять выданные наружу данные, иммутабельность массивов — меньая из ваших проблем

S>Мой код (и не только) пытается следовать гайдлайнам и защищать внутренние данные от модификации извне.

immutable массив бесполезен без поддержки immutable-типов. Пока их нет, достаточно отдавать ReadOnlyCollection и копировать аргументы (там, где это важно).

S>Проблема тут обратная. Если данные не выглядят защищенными, то почему бы не воспользоваться этим по месту и не изменить их при необходимости (Вы же не копируете каждый массив, созданный не вами?). Ой, изменили, а там где-то что-то сломалось...

При известном усердии... ну, вы поняли.
Повторюсь, если в команде низкая культура кодирования — вас ничего не спасёт. При невозможности уследить за всеми — только бить по рукам FxCop-ом.





S>Т.е. проблема не в том что кто-то пытается изменять данные, а в том что по данным (по типу) не видно, можно ли их изменять, изменятся ли они "сами" со временем, как в случае со строкой.

3 простых правила:
— Все коллекции, переданные в метод, должны рассматриваться как RO, если иное не очевидно из названия параметров/метода.
— Все коллекции, сохраняемые как значение поля, должны копироваться (исключение — для классов-обёрток).
— Все коллекции, хранимые в поле и отдаваемые наружу, должны отдаваться либо в виде r/o-обёртки, либо копией. В последнем случае должен использоваться метод GetSmth().

Разумеется, есть исключения, но они достаточно редки.

S>Вообще не так уж и сложно обеспечить себя вполне MyИммутабельнымМассивом, MyWarning-ами, MyПравилами. Но речь идет о штуке из коробки, которая может быть использована всеми, а не только мной.


Повторюсь, проблему иммутабельных данных одними неизменяемыми массивами не решить. Поэтому, либо следим за стилем кодирования, либо смиряемся с бардаком.
Re[5]: Только мне в дотнете не хватает неизменяемого массива
От: _FRED_ Черногория
Дата: 01.02.11 07:12
Оценка: +1
Здравствуйте, VladD2, Вы писали:

_FR>>Не хватает часто Но всегда удавалось обойтись ReadOnlyCollection<>

VD>Понятно, что обойтись можно. Непонятно, зачем? Зачем терять память и такты понапрасну?
_FR>>И всё-таки: где и как можно использовать "неизменяемый массив", что бы его нельзя было бы заменить ReadOnlyCollection? В голову только вариантность и приходит. Но это можно решить на уровне библиотеки.
VD>Как минимум так где эффективность кода и объем потребляемой памяти важны.
_FR>>А оверхед — ну разве что в названии типа, да он редко когда используется.
VD>Оверхэд в создании двух объектов вместо одного и в постоянном (и свершенно лишнем) доступе по ссылке.

OK, если основной (согласен, что совсем не единственный) профит — это [низкоуровневые] оптимизации, то с этим понятно. Тут, кажется, есть несколько сложностей. Во-первых, такой тип нужно спроектировать. Во-вторых, нужно сделать для него опитимизации. sealed вот с самого начала есть, но оптимизаций под него я не знаю Отсюда и малый интерес к теме — как-то не верится, что это будет сделано Майкрософтом.

VD>>>…да и исходный массив он от изменения не защищает.

_FR>>Ну так просто надо как можно скорее исходный "обернуть" и не будет этой проблемы.
VD>Это ты расскажи тем кто ошибки делает (а кто их не делает?). Лично моя практика четко показывает, что при использовании неизменяемых структур надежность кода существенно увеличивается (при его упрощении).

Совершенно верно. Но, ИМХО, пропаганда использования имеющихся и рекомендации пл проектированию новых "правильных" типов была бы гораздо полезнее, чем ругань кривого дизайна и проектирование того, чего с огромной долей вероятности скорее всего не будет Хотя было бы здорово конешно
Help will always be given at Hogwarts to those who ask for it.
Re[12]: Только мне в дотнете не хватает неизменяемого массив
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.02.11 07:30
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, samius, Вы писали:


S>>Не сильно дороже чем заполнять копированием строки


S>Embedded-cтроки очень эффективно инициализируются, а напрямую ими манипулируют относительно редко. С массивами, напротив, большинство сценариев — на заполнение/изменение/передачу буфера. Например, поблочное копирование с одного потока в другой при вашем подходе не взлетит.

А зачем использовать иммутабельные массивы для поблочного копирования?

S>>Мой код (и не только) пытается следовать гайдлайнам и защищать внутренние данные от модификации извне.


S>immutable массив бесполезен без поддержки immutable-типов. Пока их нет, достаточно отдавать ReadOnlyCollection и копировать аргументы (там, где это важно).

Не обязательно быть immutable что бы была польза от immutable массивов. Для всех Value-типов такая польза уже есть. Кроме того есть immutable из коробки — System.String. И еще куча иммутабл типов в коробках других языков (Nemerle, F#). Так что их есть достаточно что бы была польза от immutable массивов уже сейчас, не говоря о том, что некоторые создают преимущественно иммутабельные типы в своих проектах.

S>>Проблема тут обратная. Если данные не выглядят защищенными, то почему бы не воспользоваться этим по месту и не изменить их при необходимости (Вы же не копируете каждый массив, созданный не вами?). Ой, изменили, а там где-то что-то сломалось...

S>При известном усердии... ну, вы поняли.
S>Повторюсь, если в команде низкая культура кодирования — вас ничего не спасёт. При невозможности уследить за всеми — только бить по рукам FxCop-ом.
Странно, но иммутабельность стринга спасает как от попыток его модифицировать так и от попыток скоприровать его для защиты от модификации
S>



S>>Т.е. проблема не в том что кто-то пытается изменять данные, а в том что по данным (по типу) не видно, можно ли их изменять, изменятся ли они "сами" со временем, как в случае со строкой.

S>3 простых правила:
S>- Все коллекции, переданные в метод, должны рассматриваться как RO, если иное не очевидно из названия параметров/метода.
Я не против. Но рассматривание коллекции в качестве RO не гарантирует то что через милисекунду содержимое не изменится.
S>- Все коллекции, сохраняемые как значение поля, должны копироваться (исключение — для классов-обёрток).
О, копироваться. А переданный иммутабельный массив копировать не нужно. А почему исключение для оберток? Кто будет гарантировать что обернутая коллекция не изменится?
S>- Все коллекции, хранимые в поле и отдаваемые наружу, должны отдаваться либо в виде r/o-обёртки, либо копией. В последнем случае должен использоваться метод GetSmth().
RO обертка не гарантирует неизменности содержимого тому кто берет ее снаружи. А копия не может быть закэширована и должна отдаваться наружу каждый раз новая. Иммутабельный массив решил бы этот вопрос.

S>Повторюсь, проблему иммутабельных данных одними неизменяемыми массивами не решить. Поэтому, либо следим за стилем кодирования, либо смиряемся с бардаком.

Я особо не рассчитываю на внедрение иммутабельного массива. Но считаю что если бы он был внедрен хотя бы с фреймворком 2.0, то это сильно бы изменило положение вещей на текущий момент.

За стилем-то мы следим. И вот как раз изменяемый массив позволил бы следить за ним немного меньше.
Re[6]: Только мне в дотнете не хватает неизменяемого массива
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.02.11 07:42
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, VladD2, Вы писали:


VD>>Это ты расскажи тем кто ошибки делает (а кто их не делает?). Лично моя практика четко показывает, что при использовании неизменяемых структур надежность кода существенно увеличивается (при его упрощении).


_FR>Совершенно верно. Но, ИМХО, пропаганда использования имеющихся и рекомендации пл проектированию новых "правильных" типов была бы гораздо полезнее...


Пропаганда была бы полезнее если бы в рантайме и FCL были бы "правильные" коллекции. А так получается, что "правильный" тип создать не проблема, а складывание его в коллекцию приводит к получению неправильного типа. Смысл от использования правильных типов теряется.
_FR>, чем ругань кривого дизайна и проектирование того, чего с огромной долей вероятности скорее всего не будет Хотя было бы здорово конешно
ругань — конечно плохо. Но тут частенько за ругань принимается критика и позиция несогласия с принятыми решениями.
Re[5]: Только мне в дотнете не хватает неизменяемого массива
От: _FRED_ Черногория
Дата: 01.02.11 07:52
Оценка: +1
Здравствуйте, VladD2, Вы писали:

_FR>>Это всё очень интересно. Но должна быть, как мне кажется, стратегия принятия решений несколько иная (тем более есть уже устоявшаяся практика использования обычных массивов) — интересно вначале посмотреть на сценарии использования "неизменяемых массивов": всевозможные сценарии.

VD>Да на что смотреть то? Не уж то ООП совсем в мозг внедрился?

Пока больше похоже на то, что это заноза внедрилась куда-то пониже ООП у среднестатистического разработчика В общем, давайте конструктивнее, интересно же.

VD>Сценарий примитивнейший. Перестаем заниматься херней и в публичном интерфейсе тупо выставляем неизменяемые массивы, которые хранятся как неизменяемые поля объектов. Получаем потокобезопасное, эффективное решение простое в реализации как три копейки.


Нет уж. Данный этап предполагает, в том числе, рассмотрение возможного синтаксиса. Как будет выглядеть объявление? инициализация? Как имеющееся АПИ будет "сопрягаться" с новым фундаментальным типом. Например: возможно ли будет хранить в таких массивах произвольные (в том числе и изменяемые, ибо пока нет в дотнете признака неизменяемости) структуры? Так что конкретика очень важна, и без неё просто неинтересно и нечего обсуждать.

VD>В Nemerle с его get-свойствами, макрами Record и Accessor — это вообще будет красотища. Объект содержащие только лишь информацию будут до нельзя краткими.


Если постараться не обращать внимание на преимущества в оптимизациях (с этим не поспоришь), а поговорить только об удобстве проектирования, я правильно понимаю, что разница между неизменяемым массивом и ReadOnlyCollection<> только в ковариантности первых? Или что-то ещё есть, чего насквозь императивным сознанием не понять?

_FR>>Чем они предподчтительнее других, имеющихся, структур данных (и не абстрактную воду "ФП и этим всё сказано" тут нужно показать, а конкретные примеры кода. Не все возможные Различные).

VD>Простой использования, эффективностью, меньшим потреблением памяти. Разве это не очевидно? Но, конечно же, все это доступно в функциональном коде не меняющем данные, а трансформирующем их.

ОК. Следующий важный этап — это оценить стоимость реализации и прибыль от использования. Сделайте в Немерле такой "софтовый" вариант: придумайте синтаксис, начните использовать. И скажите — действительно ли будет так же удобно, как кажется и сейчас? Уверяю, что большинству заинтересованных лиц гораздо интереснее было бы ознакомиться с опытом использования, нежели с тем, как это можно было бы сделать

_FR>>Потом продемонстрировать: что вот де на, можно эмулировать через то, что есть, но при этом будут такие и такие огрехи, неприятности, которые могут оказаться значимыми тогда-то и тогда-то.

VD>А что не ясно? АТД могут эмулировать много чего. Только вот это лишнее звено. Абстракция которой не требуется при правильном проектировании. А устранение лишних абстракций (без потери выразительности и надежности) — это выгода во всех отношениях.

В общих терминах я это тоже всё прекрасно понимаю Но интерес представляют именно детали.

_FR>>Потом рассказать об оптимизациях, которые можно будет делать с такой структурой (но это кажется немного сказано, но всё ли?).

VD>Кому? Тем кто не понимает чем отличается один объект от двух плюс лишняя ссылка?

Если это единственная оптимизация — то ради неё изменять фреймворк уж точно не стоит

_FR>>Но самое интересное — примеры. Возмём существующую BCL. Где от неизменяемых массивов был бы толк? В AddRange() IEnumerable<object>, ИМХО, лучше вписывается (потому что, что бы создать из изменяемого набора, например IEnumerable<object>, неизменяемый список и передать в метод, нужно сделать копирование. Затем, что бы неизменяемый список куда-то вставить, нужно сделать ещё одно копирование).


VD>Если бы в дотнете были бы неизменяемые массивы, то многое могло бы выглядеть по другому. И при этом абстракции могли бы стать дешевле. Все же есть огромная разница в передаче ссылки на массив и создании итератора. Да, где-то важнее абстракция. Но где-то эффективность.


Если бы дженерики изначально сделали, тоже было бы очень хорошо :о)) Но это не конструктивный разговор. Топик ведь не о том, как было бы здорово, если это было бы в самом начале? Вроде как о том, стоит ли это делать сейчас? ИМХО, пока не видно, что стоит.

VD>Чтобы понять бенефиты от неизменяемых структур данных нужно начать изучат этот вопрос. Про это не одна статья и книга написана. Там много бенефитов. Это и версиооннсоть, и отсутствие в необходимости блокировок и возможность безопасно разделять данные (и возвращать ссылки на них во вне).


ReadOnlyCollection<> мне кажется неизменяемой структурой данных.
Help will always be given at Hogwarts to those who ask for it.
Re[7]: Только мне в дотнете не хватает неизменяемого массива
От: _FRED_ Черногория
Дата: 01.02.11 07:58
Оценка:
Здравствуйте, samius, Вы писали:

VD>>>Это ты расскажи тем кто ошибки делает (а кто их не делает?). Лично моя практика четко показывает, что при использовании неизменяемых структур надежность кода существенно увеличивается (при его упрощении).

_FR>>Совершенно верно. Но, ИМХО, пропаганда использования имеющихся и рекомендации пл проектированию новых "правильных" типов была бы гораздо полезнее...
S>Пропаганда была бы полезнее если бы в рантайме и FCL были бы "правильные" коллекции. А так получается, что "правильный" тип создать не проблема, а складывание его в коллекцию приводит к получению неправильного типа. Смысл от использования правильных типов теряется.

Не понял, о каких типах и каких складываниях (и, =>, что неправильного) речь?

_FR>>, чем ругань кривого дизайна и проектирование того, чего с огромной долей вероятности скорее всего не будет Хотя было бы здорово конешно

S>ругань — конечно плохо. Но тут частенько за ругань принимается критика и позиция несогласия с принятыми решениями.

Да нет, ругань — это "Не уж то ООП совсем в мозг внедрился?" и прочие уколы.
Help will always be given at Hogwarts to those who ask for it.
Re[13]: Только мне в дотнете не хватает неизменяемого массив
От: Sinix  
Дата: 01.02.11 08:02
Оценка:
Здравствуйте, samius, Вы писали:

S>А зачем использовать иммутабельные массивы для поблочного копирования?

Как минимум один из методов должен только читать из блока. Что выберете:
— ввести ro-обёртку вокруг массива;
— копировать массив в ImmutableArray и передавать уже его;
— пожертвовать абстрактной красивостью и оставить как есть
?

На практике подобных задач — с множеством вспомогательных методов — выше крыши; сценариев, когда требуется совсем неизменяемая коллекция, настолько мало, что они с головой покрываются new ReadOnlyCollection<T>(source.ToArray());

S>Не обязательно быть immutable что бы была польза от immutable массивов. ... И еще куча иммутабл типов в коробках других языков (Nemerle, F#). Так что их есть достаточно что бы была польза от immutable массивов уже сейчас, не говоря о том, что некоторые создают преимущественно иммутабельные типы в своих проектах.


Я ещё раз повторю — без возможности явно объявить о иммутабельности типа (например, generic-ограничением), вы не можете полагаться на иммутабельность данных в целом. Следовательно, RO-коллекции превращаются из повсевместной фичи в приятный хелпер. В фреймворке уже есть готовый хелпер, и он поддерживает все сценарии — и с обёрткой, и с копированием. Смысла производить фундаментальные изменения в рантайме ради одной недофичи (и изменять ещё раз — при введении полноценной поддержки immutable) я не вижу.

S>RO обертка не гарантирует неизменности содержимого тому кто берет ее снаружи.

Зачастую и не должна. Как пример — Dictionary.Keys.

S> А копия не может быть закэширована и должна отдаваться наружу каждый раз новая.

Почему? Всё та же new ReadOnlyCollection<T>(source.ToArray()).

S>Я особо не рассчитываю на внедрение иммутабельного массива. Но считаю что если бы он был внедрен хотя бы с фреймворком 2.0, то это сильно бы изменило положение вещей на текущий момент.

Да не изменило бы оно нифига. Кому надо — давно добавили extension CopyToReadOnly и соответствующее правило в FxCop. Кому не надо — философствуют на 11й(?) странице. Я явно отношусь к последним

Приведите хоть одно место в фреймворке (кроме ляпа с Path.InvalidChars), где immutable-массивы явно исправят положение к лучшему.
Re[8]: Только мне в дотнете не хватает неизменяемого массива
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.02.11 08:16
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, samius, Вы писали:


VD>>>>Это ты расскажи тем кто ошибки делает (а кто их не делает?). Лично моя практика четко показывает, что при использовании неизменяемых структур надежность кода существенно увеличивается (при его упрощении).

_FR>>>Совершенно верно. Но, ИМХО, пропаганда использования имеющихся и рекомендации пл проектированию новых "правильных" типов была бы гораздо полезнее...
S>>Пропаганда была бы полезнее если бы в рантайме и FCL были бы "правильные" коллекции. А так получается, что "правильный" тип создать не проблема, а складывание его в коллекцию приводит к получению неправильного типа. Смысл от использования правильных типов теряется.

_FR>Не понял, о каких типах и каких складываниях (и, =>, что неправильного) речь?

Повыделял выше. Речь о неизменяемых структурах и о том что их пропаганда была бы эффективнее, будь в FW или в рантайме неизменяемые коллекции. А так — смысл использования неизменяемого объекта в изменяемой коллекции ровно такой же как и у использования изменяемого объекта в изменяемой коллекции.
Re[9]: Только мне в дотнете не хватает неизменяемого массива
От: _FRED_ Черногория
Дата: 01.02.11 08:28
Оценка:
Здравствуйте, samius, Вы писали:

S>Повыделял выше. Речь о неизменяемых структурах и о том что их пропаганда была бы эффективнее, будь в FW или в рантайме неизменяемые коллекции. А так — смысл использования неизменяемого объекта в изменяемой коллекции ровно такой же как и у использования изменяемого объекта в изменяемой коллекции.


А почему ReradOnlyCollection<> изменяемая? А у меня есть ещё ReadOnlyCollection2 (которая от ICollection<>), а так же сеты и словари и мне хватает
Help will always be given at Hogwarts to those who ask for it.
Re[14]: Только мне в дотнете не хватает неизменяемого массив
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.02.11 08:35
Оценка:
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, samius, Вы писали:


S>>А зачем использовать иммутабельные массивы для поблочного копирования?

S>Как минимум один из методов должен только читать из блока. Что выберете:
S>- ввести ro-обёртку вокруг массива;
S>- копировать массив в ImmutableArray и передавать уже его;
S>- пожертвовать абстрактной красивостью и оставить как есть
S>?
То есть речь о том, что если бы были такие массивы, то в методе записи в Stream должен был бы использвоаться иммутабельный массив, и тогда для блочного копирования пришлось бы задвинуть на реюз блоков?
Вообще говоря я не предлагал переписывать фреймворк, но если бы такое случилось, я бы предпочел что бы Stream.Write принимал бы иммутабельный буфер, либо перегруженный метод, принимающий иммутабельный буфер.

S>На практике подобных задач — с множеством вспомогательных методов — выше крыши; сценариев, когда требуется совсем неизменяемая коллекция, настолько мало, что они с головой покрываются new ReadOnlyCollection<T>(source.ToArray());

Как бы ROC<T> не была создана, сам вид ROC<T> не обеспечивает видимости гарантии неизменности данных извне. Т.е. для того что бы понять, будут меняться данные или нет в этом ROC<T>, мне нужно открыть рефлектор и убедиться что ROC<T> создан с копированием данных, а не как-то иначе.

S>Я ещё раз повторю — без возможности явно объявить о иммутабельности типа (например, generic-ограничением), вы не можете полагаться на иммутабельность данных в целом. Следовательно, RO-коллекции превращаются из повсевместной фичи в приятный хелпер. В фреймворке уже есть готовый хелпер, и он поддерживает все сценарии — и с обёрткой, и с копированием. Смысла производить фундаментальные изменения в рантайме ради одной недофичи (и изменять ещё раз — при введении полноценной поддержки immutable) я не вижу.

я вижу.

S>>RO обертка не гарантирует неизменности содержимого тому кто берет ее снаружи.

S>Зачастую и не должна. Как пример — Dictionary.Keys.
Речь о неизменяемых коллекциях. Dictionary.Keys таковой не является и не может быть использована для гарантии неизменности содержимого.

S>> А копия не может быть закэширована и должна отдаваться наружу каждый раз новая.

S>Почему? Всё та же new ReadOnlyCollection<T>(source.ToArray()).
А откуда должно быть известно снаружи что содержимое этого экземеляра не изменится в будущем?

S>>Я особо не рассчитываю на внедрение иммутабельного массива. Но считаю что если бы он был внедрен хотя бы с фреймворком 2.0, то это сильно бы изменило положение вещей на текущий момент.

S>Да не изменило бы оно нифига. Кому надо — давно добавили extension CopyToReadOnly и соответствующее правило в FxCop. Кому не надо — философствуют на 11й(?) странице. Я явно отношусь к последним

S>Приведите хоть одно место в фреймворке (кроме ляпа с Path.InvalidChars), где immutable-массивы явно исправят положение к лучшему.

Даже не буду пытаться, т.к. в любом случае изменение фреймворка убьет совместимость. Однако, разработка приложений не ограничивается использованием одного только фреймворка и сопряжена с разработкой новых структур данных. В них-то и предполагается использование бенефитов иммутабельного массива.
Re[10]: Только мне в дотнете не хватает неизменяемого массив
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.02.11 08:40
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, samius, Вы писали:


S>>Повыделял выше. Речь о неизменяемых структурах и о том что их пропаганда была бы эффективнее, будь в FW или в рантайме неизменяемые коллекции. А так — смысл использования неизменяемого объекта в изменяемой коллекции ровно такой же как и у использования изменяемого объекта в изменяемой коллекции.


_FR>А почему ReradOnlyCollection<> изменяемая?

Потому что ее содержимое может измениться любым кто владеет переданной на конструктор коллекций втайне от тех кто владеет оберткой.
_FR> А у меня есть ещё ReadOnlyCollection2 (которая от ICollection<>), а так же сеты и словари и мне хватает
У меня тоже кое-что есть, мне хватает. Но проблема в том, что то что есть у меня больше никто не использует, потому что использует свои мопеды. В итоге нет ни одной неизменяемой межъязыковой коллекции.
Re[15]: Только мне в дотнете не хватает неизменяемого массив
От: Sinix  
Дата: 01.02.11 08:54
Оценка:
Здравствуйте, samius, Вы писали:


S>То есть речь о том, что если бы были такие массивы, то в методе записи в Stream должен был бы использвоаться иммутабельный массив, и тогда для блочного копирования пришлось бы задвинуть на реюз блоков?

Ну да, ваша же аргументация —

проблема не в том что кто-то пытается изменять данные, а в том что по данным (по типу) не видно, можно ли их изменять, изменятся ли они "сами" со временем, как в случае со строкой.

?
Я всего лишь довёл до абсурда, т.к. все предыдущие намёки на сомнительную полезность immutable-массивов при существующем положении дел как-то прошли мимо.

S>Вообще говоря я не предлагал переписывать фреймворк, но если бы такое случилось, я бы предпочел что бы Stream.Write принимал бы иммутабельный буфер, либо перегруженный метод, принимающий иммутабельный буфер.

А заполнялся бы этот immutable буфер копированием. Потому что в ряде сценариев буфер сначала собирают по кусочкам, из нескольких источников, а затем — скармливают в output.

S>Как бы ROC<T> не была создана, сам вид ROC<T> не обеспечивает видимости гарантии неизменности данных извне. Т.е. для того что бы понять, будут меняться данные или нет в этом ROC<T>, мне нужно открыть рефлектор и убедиться что ROC<T> создан с копированием данных, а не как-то иначе.


Это _очень_ редкий и абсолютно бесполезный для самого фреймворка юз-кейз. Поэтому или писать правило для FxCop, или создавать свою коллекцию, или писать в feedback, или ждать, пока МС вплотную займётся поддержкой неизменяемых типов данных.
Re[11]: Только мне в дотнете не хватает неизменяемого массив
От: _FRED_ Черногория
Дата: 01.02.11 09:06
Оценка:
Здравствуйте, samius, Вы писали:

S>>>Повыделял выше. Речь о неизменяемых структурах и о том что их пропаганда была бы эффективнее, будь в FW или в рантайме неизменяемые коллекции. А так — смысл использования неизменяемого объекта в изменяемой коллекции ровно такой же как и у использования изменяемого объекта в изменяемой коллекции.


_FR>>А почему ReradOnlyCollection<> изменяемая?

S>Потому что ее содержимое может измениться любым кто владеет переданной на конструктор коллекций втайне от тех кто владеет оберткой.

Ой ли? Или мы владеем тем, что передаём туда, или копируем. Поэтому не "может", а "можно сделать", если делать абы как Так что всё зависит только от того, что "заворачивает".
Help will always be given at Hogwarts to those who ask for it.
Re[16]: Только мне в дотнете не хватает неизменяемого массив
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.02.11 09:55
Оценка: 16 (1) +1
Здравствуйте, Sinix, Вы писали:

S>Здравствуйте, samius, Вы писали:


S>>То есть речь о том, что если бы были такие массивы, то в методе записи в Stream должен был бы использвоаться иммутабельный массив, и тогда для блочного копирования пришлось бы задвинуть на реюз блоков?

S>Ну да, ваша же аргументация —
S>

S>проблема не в том что кто-то пытается изменять данные, а в том что по данным (по типу) не видно, можно ли их изменять, изменятся ли они "сами" со временем, как в случае со строкой.

S>?
S>Я всего лишь довёл до абсурда, т.к. все предыдущие намёки на сомнительную полезность immutable-массивов при существующем положении дел как-то прошли мимо.
Этот намек тоже. Не вижу абсурда.

S>>Вообще говоря я не предлагал переписывать фреймворк, но если бы такое случилось, я бы предпочел что бы Stream.Write принимал бы иммутабельный буфер, либо перегруженный метод, принимающий иммутабельный буфер.

S>А заполнялся бы этот immutable буфер копированием. Потому что в ряде сценариев буфер сначала собирают по кусочкам, из нескольких источников, а затем — скармливают в output.
Так в чем проблема?

S>>Как бы ROC<T> не была создана, сам вид ROC<T> не обеспечивает видимости гарантии неизменности данных извне. Т.е. для того что бы понять, будут меняться данные или нет в этом ROC<T>, мне нужно открыть рефлектор и убедиться что ROC<T> создан с копированием данных, а не как-то иначе.


S>Это _очень_ редкий и абсолютно бесполезный для самого фреймворка юз-кейз. Поэтому или писать правило для FxCop, или создавать свою коллекцию, или писать в feedback, или ждать, пока МС вплотную займётся поддержкой неизменяемых типов данных.

Конечно редкий и бесполезный. Если бы изначально в фреймворке строки были бы изменяемыми, то сейчас бы юзкейзы с неизменяемыми строками тоже казались бы не стоящими внимания.

Sinix! Я свою точку зрения изложил, надеюсь она понятна. Мы обменялись аргументами, и судя по всему, остались при своем. То что нет иммутабельного массива я считаю серьезным упущением. На то что он появится когда-либо серьезно не рассчитываю. От того что кто-то кого-то убедит, мало что изменится в текущей ситуации, потому предлагаю на сим закончить.
Re[12]: Только мне в дотнете не хватает неизменяемого массив
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.02.11 10:02
Оценка: -1
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, samius, Вы писали:


_FR>>>А почему ReradOnlyCollection<> изменяемая?

S>>Потому что ее содержимое может измениться любым кто владеет переданной на конструктор коллекций втайне от тех кто владеет оберткой.

_FR>Ой ли? Или мы владеем тем, что передаём туда, или копируем. Поэтому не "может", а "можно сделать", если делать абы как Так что всё зависит только от того, что "заворачивает".

Что говорит о том что однозначного ответа на вопрос изменяемости данных ReadOnlyCollection нет, в сравнении со списками F#-а, или Nemerle. Все зависит от абы как, от того что и кто, и что случится когда.
Re[13]: Только мне в дотнете не хватает неизменяемого массив
От: _FRED_ Черногория
Дата: 01.02.11 10:05
Оценка:
Здравствуйте, samius, Вы писали:

_FR>>>>А почему ReradOnlyCollection<> изменяемая?

S>>>Потому что ее содержимое может измениться любым кто владеет переданной на конструктор коллекций втайне от тех кто владеет оберткой.
_FR>>Ой ли? Или мы владеем тем, что передаём туда, или копируем. Поэтому не "может", а "можно сделать", если делать абы как Так что всё зависит только от того, что "заворачивает".

S>Что говорит о том что однозначного ответа на вопрос изменяемости данных ReadOnlyCollection нет, в сравнении со списками F#-а, или Nemerle. Все зависит от абы как, от того что и кто, и что случится когда.


Вывод совершенно не верный. Сравнивать ReadOnlyCollection<> предлагается не "со списками F#-а, или Nemerle" (тогда уж надо взять имутабельный список для шарпа) а с "неизменяемым массивом".
Help will always be given at Hogwarts to those who ask for it.
Re[14]: Только мне в дотнете не хватает неизменяемого массив
От: samius Япония http://sams-tricks.blogspot.com
Дата: 01.02.11 10:17
Оценка:
Здравствуйте, _FRED_, Вы писали:

_FR>Здравствуйте, samius, Вы писали:


_FR>>>>>А почему ReradOnlyCollection<> изменяемая?


S>>Что говорит о том что однозначного ответа на вопрос изменяемости данных ReadOnlyCollection нет, в сравнении со списками F#-а, или Nemerle. Все зависит от абы как, от того что и кто, и что случится когда.


_FR>Вывод совершенно не верный. Сравнивать ReadOnlyCollection<> предлагается не "со списками F#-а, или Nemerle" (тогда уж надо взять имутабельный список для шарпа) а с "неизменяемым массивом".

(что за иммутабельный список для шарпа?)
Предполагается что содержимое неизменяемого массива нельзя изменить после создания. В этом контексте ReadOnlyCollection с ним не сравнивается.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.