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

Сообщение Re[10]: понимание ООП Алана Кея от 24.03.2023 9:42

Изменено 24.03.2023 9:46 vdimas

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

V>>Мы тут говорили о коде как о данных.

V>>Это появилось только с метаклассами в Смолтолке-80.
V>>До этого никакой рефлексии не было.
S>Рефлексия ортогональна коду-как-данным.

Является необходимым компонентом такого подхода, бо без рефлексии "код как данные" будет просто набором байт.


S>В лиспе есть код-как-данные, но рефлексии может и не быть.


Это ничем не будет отличаться от указателя на функцию в С++ с т.з. программиста.


S>В раннем дотнете рефлексия была, а кода-как-данных не было.


И как же Reflector работал? ))
А всякие AOP-ориентированные расширения?
При наличии взаимно-однозначного отображения кода на AST такие рассуждения сходу превращаются в спекуляции.


S>Код-как-данные — это Expression<T>.


Expression<T> — это "AST на блюдечке" и не более чем.
Просто высокоуровневое представление кода в виде графа, чего в общем случае не требуется, в общем-то, потому что никто не работает со всем графом "одновременно" — его обходят визиторами.
Выглядит так, что ты не понимал, при чём тут стековая машинка в течении всего этого обсуждения, блин, т.е. всё еще хуже, чем я думал.

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


Это как если запустить над графом итератор-визитор, код стековой машинки будет такой:
A C E D B H I G F
(вычисляем A, кладём на стек; вычисляем C, кладём на стек, вычисляем E, далее результаты вычислений С и E заменяются на стеке результатом вычисления D и т.д.)

Результат обхода дерева и представление кода в виде дерева(графа) взаимно однозначны.
Сответственно, трансформацию кода можно выполнять прямо по последовательности обхода, а не по графу — бо оно так в реальной жизни и происходит — через итерирование дерева.
Например, на стадии бета-редукции известные C и E могут быть заменены предвычисленным D', тогда тройка C E D в последовательности кода заменяется просто на D'.

Вот так ты грохнулся в фейсом в лужу — нет в Смолтолке никаких аналогов Expression<T>, а код как данные есть.
"Слышал звон" во всей своей красе, бгг...
Молодец, чо! Зато спорим до усрачки!


S>Рефлексия — System.Runtime.Reflection.


Да понятно, что у тебя на дотнете свет клином сошелся, хосподя.


V>>Плюс аргументами генериков не могут быть ref-структуры, поэтому, приходится описывать типы делегатов ручками как в старые добрые времена, когда генериков еще не было, бгг...

S>Это всё не относится к вопросам ООП парадигмы, а скорее о проектировании реальной платформы в условиях противоречивых ограничений.

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


V>>Да какие проблемы (мать, мать, мать...) — опиши сам объект как неизменяемый.

V>>Тебе показать, как описывать иммутабельные объекты в С++?
S>Ага, вижу, начинается понимание

Должно было начаться на много лет раньше.
Я еще в первый раз долго не мог воткнуть в ту дичь, что вместо обсуждения иммутабельных типов ты обсуждаешь методы, не изменяющие состояние объекта.
Пипец... А потом обижаешься, когда очередную такую дичь заслужено называют нубством.


V>>Но тип аргумента-объекта уже должен уже быть?

S>Конечно.

Но в рассуждениях ты об этом "забыл".


V>>1. В дотнете я могу породить мутабельный тип из IImmutableList<T> аж бегом и со свистом.

S>Породить-то можете, а что вы с ним будете делать дальше?

Подавать туда, где ожидается IImmutableList<T> и нарушать тем самым контракт иммутабельности, заложенный при проектировании.
Хулиганить, одним словом, показывая как ущербность твоих аргументов, так и отсутствие гарантий в такой системе.


S>Вы понимаете, что он будет нарушать спецификацию интерфейса?


Дошло, наконец.
А кто мне запретит нарушать?
Где эти пресловутые гарантии?
Почему я вообще должен объяснять взрослому инженеру банальности на пальцах?

Гарантии иммутабельности может иметь только сам тип.



V>>2. В этой же технике в точности аналогично можно и в С++.

S>Ага. Осталось понять, при чём тут const, и устыдиться.

Тебе уже многократно ответили, при чём тут const. Стыд тут только испанский.


S>Упражнение-то выполнить сможете?


У тебя как обычно проблема с формулировкой условий задач.
Из предыдущего твоего поста звучит так, что модификатор const должен волшебным образом привести интерфейс IList<T> к IImmutableList<T>.
Это уже не просто не смешно, это проблемки с мыслительным аппаратом.


V>>Еще в прошлые разы я обращал твоё внимание на то, что более выгодно с практической точки зрения, чтобы не твой код требовал иммутабельности объекта, а чтобы внешний код требовал, чтобы твой код не мог модифицировать объект.

S>Пытаетесь подменить задачу.

Пытаюсь достучаться до непроходимого коллеги — иммутабельность заключена в описании типа, а не в коде, обрабатывающего тип.
Код всего лишь работает в условиях ограничений.
Это не подмена задачи, это обычная принятая в IT практика, которая проистекает из основ логики — необходимость не равна достаточности.
Любое ограничение — это введение признака "необходимости".
Не обязательно ограничение const, есть еще другие модификаторы, если речь про С++.


V>>Почему так? — по очевидной причине, ведь твой код тогда сможет работать как с тру-иммутабельными объектами, так и с неиммутабльными при рождении, но которые решили сделать иммутабельными "чуть позже". Например, некий достаточно сложно инициализируемый ветвистый словарь чего-то там.

S>Ну так для того, чтобы "мой" код корректно работал, мне нужны гарантии не только того, что я не изменяю объект, но и что никто другой его тоже не изменяет.

Опиши имутабельный тип, какие проблемы?
Это ж твой код? Ну и вот. ))
У тебяя ведь нет никаких гарантий относительно IImmutableList<T>, но спать спокойно тебе это не мешает.
Забавно порой общаться со столь ангажированными личностями, однако.


S>Посмотрите, как устроен ImmutableDictionary в дотнете. Там нет const, и при этом "накладные расходы и прессинг на память" ровно такие же, как в вашем сценарии.


Бгг, ну так и сравни кол-во выделений из кучи для мильона вхождений в случае обычного словаря и иммутабельного.
Разница в мильон раз.


V>>В С+ в этом сценарии достаточно скопировать ссылку/указатель.

S>Ну нет конечно, недостаточно.

Достаточно.


S>С++ не даст мне гарантии, что кто-то не поменяет этот словарь после того, как я заложился на его неизменность.


Не кто-то, а ты, как программист.
Пишешь функцию инициализации такого словаря, возвращаешь из неё const ссылку/указатель на этот словарь.
"Внешний" код будет обладать только константной ссылкой, гарантии соблюдены, ву а ля.
То бишь, со своей стороны кода ты достаточностью автоматом покрыл необходимость.
Л — логика!


S>Перед тем, как рассуждать об эффективности кода, нужно обеспечить его корректность.


Тебе уже много лет назад на пальцах объяснили, что весь достаточный для этого инструментарий присутствует.
Я просто не догадался тогда, что ты не в курсе, как описывать иммутабельные объекты в С++.

Скажем так, тебе долго удавалось водить коллег за нос, выдавая себя за хорошо соображающего.
Прошли годы, ты стал смеле, "раскрылся", сегодня я сразу предположил, что ты банально не втыкаешь, путаешь два важных, но разных кейза (пусть даже второй кейз покрывается первым, но он не теряет важность и в случае самостоятельного использования).
И я оказался прав!
Ты действительно не отличаешь одно от другого.
Да и вообще, плохо понимаешь, как распространяются гарантии.
Пришлось напоминать, что если гарантии нужны железобетонные, то они и должны идти с самого начала — с объявления типов (полей таких типов).
Код уже работает над объявлеными типами (и полями, если это методы).

Не зря этот подход был скопирован из С++ в C# для структур.
А для классов по прежнему глухо — IImmutableList<T> не обеспечивает ни необходимости, ни достаточности.
Поэтому твои вопросы
Re[10]: понимание ООП Алана Кея
Здравствуйте, Sinclair, Вы писали:

V>>Мы тут говорили о коде как о данных.

V>>Это появилось только с метаклассами в Смолтолке-80.
V>>До этого никакой рефлексии не было.
S>Рефлексия ортогональна коду-как-данным.

Является необходимым компонентом такого подхода, бо без рефлексии "код как данные" будет просто набором байт.


S>В лиспе есть код-как-данные, но рефлексии может и не быть.


Это ничем не будет отличаться от указателя на функцию в С++ с т.з. программиста.


S>В раннем дотнете рефлексия была, а кода-как-данных не было.


И как же Reflector работал? ))
А всякие AOP-ориентированные расширения?
При наличии взаимно-однозначного отображения кода на AST такие рассуждения сходу превращаются в спекуляции.


S>Код-как-данные — это Expression<T>.


Expression<T> — это "AST на блюдечке" и не более чем.
Просто высокоуровневое представление кода в виде графа, чего в общем случае не требуется, в общем-то, потому что никто не работает со всем графом "одновременно" — его обходят визиторами.
Выглядит так, что ты не понимал, при чём тут стековая машинка в течении всего этого обсуждения, блин, т.е. всё еще хуже, чем я думал.

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


Это как если запустить над графом итератор-визитор, код стековой машинки будет такой:
A C E D B H I G F
(вычисляем A, кладём на стек; вычисляем C, кладём на стек, вычисляем E, далее результаты вычислений С и E заменяются на стеке результатом вычисления D и т.д.)

Результат обхода дерева и представление кода в виде дерева(графа) взаимно однозначны.
Сответственно, трансформацию кода можно выполнять прямо по последовательности обхода, а не по графу — бо оно так в реальной жизни и происходит — через итерирование дерева.
Например, на стадии бета-редукции известные C и E могут быть заменены предвычисленным D', тогда тройка C E D в последовательности кода заменяется просто на D'.

Вот так ты грохнулся в фейсом в лужу — нет в Смолтолке никаких аналогов Expression<T>, а код как данные есть.
"Слышал звон" во всей своей красе, бгг...
Молодец, чо! Зато спорим до усрачки!


S>Рефлексия — System.Runtime.Reflection.


Да понятно, что у тебя на дотнете свет клином сошелся, хосподя.


V>>Плюс аргументами генериков не могут быть ref-структуры, поэтому, приходится описывать типы делегатов ручками как в старые добрые времена, когда генериков еще не было, бгг...

S>Это всё не относится к вопросам ООП парадигмы, а скорее о проектировании реальной платформы в условиях противоречивых ограничений.

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


V>>Да какие проблемы (мать, мать, мать...) — опиши сам объект как неизменяемый.

V>>Тебе показать, как описывать иммутабельные объекты в С++?
S>Ага, вижу, начинается понимание

Должно было начаться на много лет раньше.
Я еще в первый раз долго не мог воткнуть в ту дичь, что вместо обсуждения иммутабельных типов ты обсуждаешь методы, не изменяющие состояние объекта.
Пипец... А потом обижаешься, когда очередную такую дичь заслужено называют нубством.


V>>Но тип аргумента-объекта уже должен уже быть?

S>Конечно.

Но в рассуждениях ты об этом "забыл".


V>>1. В дотнете я могу породить мутабельный тип из IImmutableList<T> аж бегом и со свистом.

S>Породить-то можете, а что вы с ним будете делать дальше?

Подавать туда, где ожидается IImmutableList<T> и нарушать тем самым контракт иммутабельности, заложенный при проектировании.
Хулиганить, одним словом, показывая как ущербность твоих аргументов, так и отсутствие гарантий в такой системе.


S>Вы понимаете, что он будет нарушать спецификацию интерфейса?


Дошло, наконец.
А кто мне запретит нарушать?
Где эти пресловутые гарантии?
Почему я вообще должен объяснять взрослому инженеру банальности на пальцах?

Гарантии иммутабельности может иметь только сам тип.



V>>2. В этой же технике в точности аналогично можно и в С++.

S>Ага. Осталось понять, при чём тут const, и устыдиться.

Тебе уже многократно ответили, при чём тут const. Стыд тут только испанский.


S>Упражнение-то выполнить сможете?


У тебя как обычно проблема с формулировкой условий задач.
Из предыдущего твоего поста звучит так, что модификатор const должен волшебным образом привести интерфейс IList<T> к IImmutableList<T>.
Это уже не просто не смешно, это проблемки с мыслительным аппаратом.


V>>Еще в прошлые разы я обращал твоё внимание на то, что более выгодно с практической точки зрения, чтобы не твой код требовал иммутабельности объекта, а чтобы внешний код требовал, чтобы твой код не мог модифицировать объект.

S>Пытаетесь подменить задачу.

Пытаюсь достучаться до непроходимого коллеги — иммутабельность заключена в описании типа, а не в коде, обрабатывающего тип.
Код всего лишь работает в условиях ограничений.
Это не подмена задачи, это обычная принятая в IT практика, которая проистекает из основ логики — необходимость не равна достаточности.
Любое ограничение — это введение признака "необходимости".
Не обязательно ограничение const, есть еще другие модификаторы, если речь про С++.


V>>Почему так? — по очевидной причине, ведь твой код тогда сможет работать как с тру-иммутабельными объектами, так и с неиммутабльными при рождении, но которые решили сделать иммутабельными "чуть позже". Например, некий достаточно сложно инициализируемый ветвистый словарь чего-то там.

S>Ну так для того, чтобы "мой" код корректно работал, мне нужны гарантии не только того, что я не изменяю объект, но и что никто другой его тоже не изменяет.

Опиши имутабельный тип, какие проблемы?
Это ж твой код? Ну и вот. ))
У тебяя ведь нет никаких гарантий относительно IImmutableList<T>, но спать спокойно тебе это не мешает.
Забавно порой общаться со столь ангажированными личностями, однако.


S>Посмотрите, как устроен ImmutableDictionary в дотнете. Там нет const, и при этом "накладные расходы и прессинг на память" ровно такие же, как в вашем сценарии.


Бгг, ну так и сравни кол-во выделений из кучи для мильона вхождений в случае обычного словаря и иммутабельного.
Разница в мильон раз.


V>>В С+ в этом сценарии достаточно скопировать ссылку/указатель.

S>Ну нет конечно, недостаточно.

Достаточно.


S>С++ не даст мне гарантии, что кто-то не поменяет этот словарь после того, как я заложился на его неизменность.


Не кто-то, а ты, как программист.
Пишешь функцию инициализации такого словаря, возвращаешь из неё const ссылку/указатель на этот словарь.
"Внешний" код будет обладать только константной ссылкой, гарантии соблюдены, ву а ля.
То бишь, со своей стороны кода ты достаточностью автоматом покрыл необходимость.
Л — логика!


S>Перед тем, как рассуждать об эффективности кода, нужно обеспечить его корректность.


Тебе уже много лет назад на пальцах объяснили, что весь достаточный для этого инструментарий присутствует.
Я просто не догадался тогда, что ты не в курсе, как описывать иммутабельные объекты в С++.

Скажем так, тебе долго удавалось водить коллег за нос, выдавая себя за хорошо соображающего.
Прошли годы, ты стал смеле, "раскрылся", сегодня я сразу предположил, что ты банально не втыкаешь, путаешь два важных, но разных кейза (пусть даже второй кейз покрывается первым, но он не теряет важность и в случае самостоятельного использования).
И я оказался прав!
Ты действительно не отличаешь одно от другого.
Да и вообще, плохо понимаешь, как распространяются гарантии.
Пришлось напоминать, что если гарантии нужны железобетонные, то они и должны идти с самого начала — с объявления типов (полей таких типов).
Код уже работает над объявлеными типами (и полями, если это методы).

Не зря этот подход был скопирован из С++ в C# для структур.
А для классов по прежнему глухо — IImmutableList<T> не обеспечивает ни необходимости, ни достаточности.
Поэтому твои вопросы