Информация об изменениях

Сообщение Re[16]: понимание ООП Алана Кея от 29.03.2023 15:02

Изменено 29.03.2023 15:06 vdimas

Re[16]: понимание ООП Алана Кея
Здравствуйте, Sinclair, Вы писали:

S>>>IReadOnlySet, IReadOnlyList и прочие никакого отношения к иммутабельности не имеют.

V>>Имеют такое же отношение, как и IImutableList и Ко.
V>>Это высказывание — вполне себе тезис.
S>Ну да, совершенно верно. Это — ошибочный тезис.
S>Иммутабельность означает не просто отсутствие модифицирующих операций, но и наличие операций по построению новых значений на основе существующих.

Ну что опять за детсад, мистер коллега с большим стажем?
Речь про встроенные в язык "операции" или библиотечного уровня?
Если второе (а оно второе), то тезис перестаёт быть ошибочным, т.к. есть возможность написать аналогичную функциональность над готовыми read-only-design типами с публичными конструкторами.
(или защищёнными такими конструкторами... облом расписывать всю комбинаторику достаточных условий)


V>>Я на это уже отвечал — там речь лишь о некоторых алгоритмах над некоторыми иммутабельныим структурами данных.

S>Ткните пальцем хотя бы в один "алгоритм" в этом неймспейсе.

Например, алгоритм балансировки RB-дерева внутри ImmutableSet и ImmutableDictionary.
Если мне нужны другие алгоритмы, берутся интерфейсы IImmutableSet и IImmutableDictionary, и делаются другие реализации.

Поэтому, абстрактный код над иммутабельными типами данных стоит писать на основе интерфейсов (ограничений в интерфейсах, в т.ч. для value-type реализаций, которые имеют смысл фасада над внутренними ссылочными узлами дерева), а не конкретных классов.
И тут мы возвращаемся в самое начало — для интерфейсов никакой иммутабельной реализации не гарантируется.
Круг замкнулся. ))


V>>Есть несколько конекретных типов, помеченные как sealed, которые согласно дизайну являются иммутабельными.

S>А то.

А то, что это убого в рассуждениях — нельзя подменять иммутабельность как таковую на достаточно узкую конкретную реализацию.
А потом имеешь нахальство утверждать, что окружающие "не понимают иммутабельности".
Окружающие всё понимают и потихоньку ржут или недоумевают.

Уверен, каждый первый коллега, дочитавший до сюда, многократно сделает рука-лицо...
Разве что совсем новичкам в отрасли будет полезны наши бодания.


V>>А система реализованных интерфейсов — нет, это просто "вербальные соглашения".

S>Всё верно. Причём достаточно внятные вербальные соглашения.

Да хоть какие внятные, они вербальные.
Про вербальные соглашения изначально не имело смысла спорить.


S>В принципе, любой интерфейс, помимо названий методов, оперирует некоторыми вербальным соглашениями. Нарушение которых компилятором не карается, но может привести к неожиданному поведению (в том числе и к багам).


Разумеется.
Но "железная" гарантия иммутабельности даёт возможность одновременного доступа к данным без блокировок, а это уже не семантическая потенциальная ошибка, а вполне себе хардкорная техническая, которая, будучи совершённой, приводит к плохообнаруживаемым достаточно серьёзным проблемам.


V>>Например, интерфейс IImutableDictionary может быть реализован не только на красно-чёрных деревьях.

S>А то. У нас с одногруппником в качестве курсовой работы была реализация IImmutableList и IImmutableDictionary на другой основе.

Т.е. понимаешь аргументы оппонента, но всё-равно споришь. ))


V>>И может быть реализован не только в иммутабельном виде.

S>Может, но это всё сломает.

При гарантиях read-only не сломает при одновременном доступе.
Тут опять дихотомия необходимости и достаточности.

Read-only — одна из необходимостей для описанного выше.
Еще необходимо совместное владение данными из разных потоков с контролем времени жизи.

Immutable+GC — достаточность, автоматом покрывает необходимости read-only + совместного владения в конкретном сценарии.
Но это не единственная связка, образующая достаточность, ес-но.
И встроенных immutable-гарантий для интерфейсов и абстрактных классов в дотнете нет, увы.


S>А вот в read-only виде его реализовать эффективно очень затруднительно, если вообще возможно.


Ой, блин...
Все типы неймспейса Immutable — они read-only by design.
Примерно как String, где Substring или operator+ порождают другой экземпляр.

Одно синоним другому, как и константность ("постоянство" по-русски).


V>>Что, однако, верно только для сценариев, где данные активно изменятся.

V>>FrozenXXX были созданы для других сценариев — где данные читаются намного чаще, чем изменяются.
S>Да, для специального узкого случая.

Э, нет, случай как раз не узкий.
Я понимаю, что ты мне вернул определение "узкий", но я говорил про "узость" реализации, а не сценариев.
Это две прям очень большие разницы.
Сценарии широки и там, и там, бо это два основных сценария работы с данными.


S>Вы готовы навскидку сказать, насколько они эффективнее Immutable-аналогов?


От данных зависит.
Разве ты не знаешь оценки сложности сверху сбалансированного дерева и хеш-таблицы?
Да и при оценке снизу затраты на линейный на небольшой выборке в 2-3 раза меньше, чем на хеш-таблицу или обход графа таких же размеров.


V>>* мы именно с тобой обсуждали N-арные деревья, т.е. ты должен хорошо понимать, что нет никакого запрета строить иммутабельные деревья из таких структур данных, сбалансированных с точностью от 1 до некоего выбранного max N узлов; т.е., при создании нового корня дерева в общем случае будут создаваться копии меньшего кол-ва узлов, чем для двоичных узлов, но в каждом узле будет больше элементов. До какого-то N это выгодная стратегия на современном оборудовании, потому что деревянная в памяти структура в общем случае обладает худшей локальностью, т.е. синтетические тесты, где в памяти только содаются узлы тестируемого дерева, могут сильно врать насчёт его эффективности.

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

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


V>>N-арное дерево в этом смысле — это обеспеченный ручками некий фактор локальности данных. В идеале, конечно, было бы удобно иметь ср-ва располагать такие "корзины" по границам кеш-линееек проца, но дотнету такие радости недоступны.

S>Прекрасно доступны, надо просто уметь их готовить.

Они доступны только через unmanaged, но это тогда ср-ва чуть ли не чистого Си, включенного в C# как подмножество.
И ты не сможешь эффективно ссылаться из таких структур на GC-типы, только через GC-handle, а это тормоза, т.е. профанация изначальной идеи сбацать реализацию пошустрее.


V>>В любом случае, рассуждать об иммутабельности или нет немспейса Frozen было заведомо глупо — типы данных там точно так же иммутабельны by design, как и в неймспейсе Immutable.

S>Тогда зачем вы притащили его обсуждение в эту ветку?

Обиделся? ))
А зачем ты притащил Immutable?

Я притащил для демонстрации, конечно.
Демонстрации того, что парадигма не равна конкретной реализации.
Конкретная реализация может придерживаться некоей стратегии, исходя из знаний (предположений) о характере данных и способах оперирования ими.
Re[16]: понимание ООП Алана Кея
Здравствуйте, Sinclair, Вы писали:

S>>>IReadOnlySet, IReadOnlyList и прочие никакого отношения к иммутабельности не имеют.

V>>Имеют такое же отношение, как и IImutableList и Ко.
V>>Это высказывание — вполне себе тезис.
S>Ну да, совершенно верно. Это — ошибочный тезис.
S>Иммутабельность означает не просто отсутствие модифицирующих операций, но и наличие операций по построению новых значений на основе существующих.

Ну что опять за детсад, мистер коллега с большим стажем?
Речь про встроенные в язык "операции" или библиотечного уровня?
Если второе (а оно второе), то тезис перестаёт быть ошибочным, т.к. есть возможность написать аналогичную функциональность над готовыми read-only-design типами с публичными конструкторами.
(или защищёнными такими конструкторами... облом расписывать всю комбинаторику достаточных условий)


V>>Я на это уже отвечал — там речь лишь о некоторых алгоритмах над некоторыми иммутабельныим структурами данных.

S>Ткните пальцем хотя бы в один "алгоритм" в этом неймспейсе.

Например, алгоритм балансировки RB-дерева внутри ImmutableSet и ImmutableDictionary.
Если мне нужны другие алгоритмы, берутся интерфейсы IImmutableSet и IImmutableDictionary, и делаются другие реализации.

Поэтому, абстрактный код над иммутабельными типами данных стоит писать на основе интерфейсов (ограничений в интерфейсах, в т.ч. для value-type реализаций, которые имеют смысл фасада над внутренними ссылочными узлами дерева), а не конкретных классов.
И тут мы возвращаемся в самое начало — для интерфейсов никакой иммутабельной реализации не гарантируется.
Круг замкнулся. ))


V>>Есть несколько конекретных типов, помеченные как sealed, которые согласно дизайну являются иммутабельными.

S>А то.

А то, что это убого в рассуждениях — нельзя подменять иммутабельность как таковую на достаточно узкую конкретную реализацию.
А потом имеешь нахальство утверждать, что окружающие "не понимают иммутабельности".
Окружающие всё понимают и потихоньку ржут или недоумевают.

Уверен, каждый первый коллега, дочитавший до сюда, многократно сделает рука-лицо...
Разве что совсем новичкам в отрасли будет полезны наши бодания.


V>>А система реализованных интерфейсов — нет, это просто "вербальные соглашения".

S>Всё верно. Причём достаточно внятные вербальные соглашения.

Да хоть какие внятные, они вербальные.
Про вербальные соглашения изначально не имело смысла спорить.


S>В принципе, любой интерфейс, помимо названий методов, оперирует некоторыми вербальным соглашениями. Нарушение которых компилятором не карается, но может привести к неожиданному поведению (в том числе и к багам).


Разумеется.
Но "железная" гарантия иммутабельности даёт возможность одновременного доступа к данным без блокировок, а это уже не семантическая потенциальная ошибка, а вполне себе хардкорная техническая, которая, будучи совершённой, приводит к плохообнаруживаемым достаточно серьёзным проблемам.


V>>Например, интерфейс IImutableDictionary может быть реализован не только на красно-чёрных деревьях.

S>А то. У нас с одногруппником в качестве курсовой работы была реализация IImmutableList и IImmutableDictionary на другой основе.

Т.е. понимаешь аргументы оппонента, но всё-равно споришь. ))


V>>И может быть реализован не только в иммутабельном виде.

S>Может, но это всё сломает.

При гарантиях read-only не сломает при одновременном доступе.
Тут опять дихотомия необходимости и достаточности.

Read-only — одна из необходимостей для описанного выше.
Еще необходимо совместное владение данными из разных потоков с контролем времени жизи.

Immutable+GC — достаточность, автоматом покрывает необходимости read-only + совместного владения в конкретном сценарии.
Но это не единственная связка, образующая достаточность, ес-но.
И встроенных immutable-гарантий для интерфейсов и абстрактных классов в дотнете нет, увы.


S>А вот в read-only виде его реализовать эффективно очень затруднительно, если вообще возможно.


Ой, блин...
Все типы неймспейса Immutable — они read-only by design.
Примерно как String, где Substring или operator+ порождают другой экземпляр.

Одно синоним другому, как и константность ("постоянство" по-русски).


V>>Что, однако, верно только для сценариев, где данные активно изменятся.

V>>FrozenXXX были созданы для других сценариев — где данные читаются намного чаще, чем изменяются.
S>Да, для специального узкого случая.

Э, нет, случай как раз не узкий.
Я понимаю, что ты мне вернул определение "узкий", но я говорил про "узость" реализации, а не сценариев.
Это две прям очень большие разницы.
Сценарии широки и там, и там, бо это два основных общих сценария работы с данными.


S>Вы готовы навскидку сказать, насколько они эффективнее Immutable-аналогов?


От данных зависит.
Разве ты не знаешь оценки сложности сверху сбалансированного дерева и хеш-таблицы?
Да и при оценке снизу затраты на линейный на небольшой выборке в 2-3 раза меньше, чем на хеш-таблицу или обход графа таких же размеров.


V>>* мы именно с тобой обсуждали N-арные деревья, т.е. ты должен хорошо понимать, что нет никакого запрета строить иммутабельные деревья из таких структур данных, сбалансированных с точностью от 1 до некоего выбранного max N узлов; т.е., при создании нового корня дерева в общем случае будут создаваться копии меньшего кол-ва узлов, чем для двоичных узлов, но в каждом узле будет больше элементов. До какого-то N это выгодная стратегия на современном оборудовании, потому что деревянная в памяти структура в общем случае обладает худшей локальностью, т.е. синтетические тесты, где в памяти только содаются узлы тестируемого дерева, могут сильно врать насчёт его эффективности.

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

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


V>>N-арное дерево в этом смысле — это обеспеченный ручками некий фактор локальности данных. В идеале, конечно, было бы удобно иметь ср-ва располагать такие "корзины" по границам кеш-линееек проца, но дотнету такие радости недоступны.

S>Прекрасно доступны, надо просто уметь их готовить.

Они доступны только через unmanaged, но это тогда ср-ва чуть ли не чистого Си, включенного в C# как подмножество.
И ты не сможешь эффективно ссылаться из таких структур на GC-типы, только через GC-handle, а это тормоза, т.е. профанация изначальной идеи сбацать реализацию пошустрее.


V>>В любом случае, рассуждать об иммутабельности или нет немспейса Frozen было заведомо глупо — типы данных там точно так же иммутабельны by design, как и в неймспейсе Immutable.

S>Тогда зачем вы притащили его обсуждение в эту ветку?

Обиделся? ))
А зачем ты притащил Immutable?

Я притащил для демонстрации, конечно.
Демонстрации того, что парадигма не равна конкретной реализации.
Конкретная реализация может придерживаться некоей стратегии, исходя из знаний (предположений) о характере данных и способах оперирования ими.