Re[9]: понимание ООП Алана Кея
От: Sinclair Россия https://github.com/evilguest/
Дата: 23.03.23 02:18
Оценка: :)
Здравствуйте, vdimas, Вы писали:
V>RTFM чего именно?
Истории Паскаля.

V>Сам же привёл пример конкретной системы gemstone, т.е. имелась ввиду соответствующая инфраструктура в этой системе.

Инфраструктура построена на каких-то основах.

S>>Ну, так как мне воспользоваться этим кодом изнутри VB?

V>Языками более низкого уровня.
V>Или расписать некий фреймворк оперирования памятью в некоей библиотеке и сделать импорт функций в VB (есть такая возможность), чтобы иметь требуемый инструментарий.
V>Например, можно взять готовую либу CRT.
Давайте пример кода на VB, который при помощи готовой либы CRT отправляет пользовательский предикат на сервер для исполнения.

V>Потому что в объектных файлах содержится код и данные со всей сопутствующей метаинформацией.

Это совершенно никак не связано с возможностями по манипуляции кодом как данными изнутри языка программирования.
Я не понимаю, почему эта очевидная вещь до вас не доходит. Компиляция в .obj была принята для практически 100% языков программирования; при этом возможностей мета-манипуляций в рантайме не было практически нигде.

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

В первую очередь требуется возможность этот код описать в посылаемом виде.
V>Я уже начинаю подозревать, что ты видишь возможность переносимости кода только в виде его AST-представления.
Вы перескакиваете через ступеньку, пытаясь рассуждать об исполнении, как будто возможность породить такой код у вас есть.
Это во-первых.
Во-вторых, для систем типа GemStone возможность получить код в виде AST, а не байт-кода, является необходимостью.
Потому, что предикат не исполняется напрямую. СУБД на основе предиката строит план исполнения запроса, в котором одна часть предиката будет ключом поиска в индексе, другая будет фильтром по этому индексу, а третья будет вычисляться по связанной с индексом таблице. Это вам ликбез на пальцах.
Предикат, записанный в виде императивного байт-кода, таким преобразованиям поддаётся плохо либо никак.

V>В общем, твоя попытка рассуждать о банальностях как об откровениях малость сбивает меня с толку. ))

Ну так а что делать, если вы не понимаете элементарных вещей?

V>Провожу ликбез.



V>Хосподя, Алан Кей тот еще болтун, навроде тебя.

V>Причём, болтуном он стал гораздо позже... в попытках, не знаю, придать некую публичную окраску своей роли в этой работе.
А-а, ну вы-то, конечно, лучше Кея знаете, как там всё обстояло.

V>Такие монстры как Голдберг служили неплохим противовесом этому, в общем-то, нубу-самоучке.

А что, Голдберг где-то заявляла, что язык Smalltalk был вдохновлён Фортом?

V>Какой там в опу Лисп? ))

Да почитайте же уже The Early History of Smalltalk и перестаньте позориться.

V>Похоже, ты не трогал толком ни Смолтолк, ни Лисп, ни Форт, не понимаешь внутренней механики этих языков, но пытаешься фантазировать.

Вы всё время путаете дизайн языков с внутренней механикой компилятора и рантайма.

V>Рассуждать о Лиспе можно было лишь в последней версии Смолтолка-80, когда добавили метаклассы.

V>ООП в виде CLOS привнесли в 70-х в виде стандарта, напомню, и это всего лишь эмуляция ООП на библиотечном уровне.
V>Но концепции обкатывались, не без этого.


V>Т.е. в изначальном Лиспе никаких метаклассов не было, как и не было в Лиспе ООП, ес-но, были только ф-ии как первоклассные объекты (сам код) и данные в виде однонаправленно связанных встроенных в систему списков.

Конечно не было. Именно это Кей и реализовал — ему хотелось сделать систему, которая была построена на минимуме примитивов, как Лисп, но с ООП. Если бы в Лиспе было ООП, то Smalltalk бы и не понадобился.
V>Просто ссылаться на Лисп однажды стало модно, бгг, и этот болтун не преминул.


V>Курить, что есть шитый код.

Я знаю, что такое шитый код. Какое отношение он имеет к дизайну языка Smalltalk?

V>Пример развития Форта до переносимости м/у устройствами.

По-прежнему не понимаю, какое отношение Постскрипт с его переносимостью имеет к ООП Алана Кея.

V>Таки, самообразованием принято заниматься самостоятельно, не испытывая терпение коллег.

Ну так займитесь. Почему вы вместо того, чтобы почитать первоисточники, занимаетесь гаданием на МК-51?


S>>Попробуйте реализовать на Паскале, Си, и С++ функцию, которая бы передавала пользовательский предикат на сервер для исполнения.

V>Не вижу технических проблем передать чистую ф-ию или чистое замыкание при наличии соотв. инфраструктуры.
Пример кода в студию. Хотя бы на одном из языков.

V>Напомню, что MS компилятор С++ умеет компиллировать unamanaged C++ код (т.е. безо-всяких managed расширений) в чистый байт-код.

V>(тип генерируемого образа для режима С++/CLI задаётся опциями компилятора)
Ну ок, если вам будет проще — попробуйте изобразить требуемую функциональность на unmanaged C++, скомпилированном в чистый байт-код.


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


V>Ну вот попробуй на Лисп (или другом динамическом языке) без динамического исполнения текстовых исходников, а я поржу.

Посмотрите на то, как устроены макросы Лиспа. Там нет ничего про динамическое исполнение текстовых исходников.
Всё построено на манипуляциях кодом в виде AST. Можете начинать ржать.

V>Да не связана.

V>Такая возможность связана с представлением исполняемого кода, а это представление перпендикулярно языку.


V>Похоже, у тебя каша в голове из св-в языков и конкретных их компиляторов/интерпретаторов.

Всё ровно наоборот — это у вас каша.

V>Посмотри на Схему — вот тебе оптимизирующий компилятор Лиспа.

V>Были убраны возможности рантайм рефлексии кода.
V>Язык, по-сути, тот же.
V>Отличается представлением скомпиллированного кода, а значит, особенностями модели вычисления.
И самое замечательное, что эти особенности модели вычисления никак не влияют на то, о чём я говорю.
Макросы в Схеме всё ещё есть, и это означает, что я могу решить обозначенную задачу и на схеме тоже.
А всё потому, что решают тут свойства языка. Что там под капотом — дело десятое.

V>Не осенило еще? ))

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

V>Например, MS Visual Basic for DOS компиллировал в неплохо оптимизированный код (я курочил дизассемблером что он там порождает — да там офигенно, на уровне их же компилятора Си и Паскаля).

Да видел конечно. Толку-то? Ни на одном из этих бейсиков я не могу отправить на сервер код пользовательского предиката.

V>В Лисп точно так же может сосуществовать сколько угодно много независимых ООП-подсистем библиотечного уровня.

Я в курсе. Синтаксис Лиспа настолько ужасен, что его ничем испортить нельзя. Поэтому всякие надстройки над ним выглядят не хуже оригинального лиспа.
И можно делать любое ООП, которое нравится — с наследованием интерфейсов и наследованием реализации, со множественным наследованием и без, с любыми наборами модификаторов "видимости" мемберов. Можно придумывать свойства и события; можно делать наследование экземпляров как в JS; можно обрабатывать неизвестные сообщения, как в Smalltalk.
Правда, всё это будет всё в том же ужасном стиле скобок поверх скобок. Но на фоне остального лисп-кода выделяться не будет.

В общем, Лисп считать ОО-языком бессмысленно.

V>Ты не понимаешь мотива принятия некоторых важных решений в IT в ретроспективе.


V>Проводимый ликбез тебя коробит, но это особенности твоего чванства и ничего более.
Скорее, это особенности вашего чванства.
V>В интересные места ведь тебя отсылаю. ))
Практически во всех этих местах я был. Вы что, всеръёз считаете, что я не в курсе кнутовского MIX-а, или никогда не слышал про Forth?

V>Ключевое тут то, что с помощью базовых примитивов можно расписать сколь угодно сложную систему управления динамической памятью, если по каким-то причинам не устраивает данная изкаробки. В том числе запросто пишется консервативный GC с любой из политик работы, например, какие были приняты в различных реализациях Лиспа — автоматический вызов при исчерпании пула ячеек vs явные вызовы GC.

Повторюсь: ООП-компилятор можно написать на не-ОО языке. Это ничего не говорит об ОО-свойствах этого языка.


V>Исходный GC связывал освобождаемые ячейки CONS в глобальный список свободных ячеек и не умел ничего более.

V>Перемещающи/копирующий GC должен уметь корректировать ссылки, а GC Лиспа той эпохи этого не делал.
V>(Не берусь утверждать за некие потенциальные новые реализации, бо за современным Лиспом не слежу, но десятилетиями оно работало именно так)
Наверняка вы что-то не так поняли. Весь смысл сборщика мусора — в возможности освободить занятую память.
Если сборщик ничего не перемещает, то откуда возьмётся освобождение? И вообще, зачем такой "сборщик" выполнять?
V>Не-а.
Может быть, я чего-то не понимаю. Вас не затруднит найти ссылку на описание того сборщика мусора, о котором вы рассуждаете?

V>По VB и VFoxPro литературы мильон.

Не по VB, а по ООП на VB. Примеры к "паттернам ООП" на каком языке даны?

V>Я говорю не про игнор, а про наложенные ограничения на реализацию парадигмы.

V>Джава наложила то ограничение, что экземпляры пользовательских типов будут всегда располагаться в динамической куче, а такого ограничения в исходной парадигме нет.
V>Это подробности конкретной реализации в неких принятых ограничениях.
Опять вы закапываетесь в подробности конкретной реализации. Зачем ?
В парадигме ООП нет ничего ни про кучу, ни про стек.

V>Сотый раз повторюсь — этого не требовалось.

V>Приличный "почти современный" ООП был реализован еще до Смолтолка, в Алгол-68, и там был функциональный тип и лямбды, т.е. лямбда-исчисление.

V>Я уже подкидывал тебе мысль, что ФП-подход — это подход системы ограничений к процедурному программированию (функциональный тип был известен еще в эпоху процедурного программирования), в то время как ООП-подход — это инструментарий расширения.

Это неудачная мысль.

V>ООП-подход включил известные на тот момент парадигмы целиком.

V>Дальнейшее развитие ООП-парадигмы и соотв. языков шло в области описания таких ограничений, коль они требуются, ср-вами языка.
V>Именно поэтому современные ООП-языки принято считать "мультипарадигменными", хотя это не так, разумеется.
Нет конечно.

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


V>Мда... Будем разгребать:

Вы просто написали то же самое, что и я, только более подробно.

V>А разгрести эту кашу можно лишь помня, что в ФП действует "утиная типизация", то бишь, такие функциональные объекты с одинаковой сигнатурой считаются одинаковым типом.

V>И оно не просто так, а потому что бинарная механика реализаций таких объектов идентична, т.е. бинарной ошибки реинтерпретации памяти быть не может.
Вы ставите телегу впереди лошади. В ФП совместимость между собой функций с одинаковой сигнатурой является частью дизайна языка. Бинарная механика просто построена так, чтобы удовлетворять этому требованию.
V>В дотнете, однако, делегаты с одинаковой сигнатурой неприводимы друг к другу, хотя обладают такой же бинарной совместимостью.
V>В этом месте ФП в дотнете заканчивается, толком не начавшись.


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

V>Ага, т.е. ты хорошо понимаешь про утиную типизацию, просто Ваньку тут валяешь.
Конечно понимаю.
V>Номинативная типизация — это тоже левое ограничение, не требуемое для реализации концепции ООП.
V>Это просто такое решение, ограничиться именно ею.
V>Хотя, базовая машинка способна вызывать методы не того объекта через свою систему команд, а вся "загвоздка" была бы только в верификации сгенерированного компилятором кода, верно?
V>Т.е. всего-то надо было снабдить верификатор возможностью утиной типизации неких типов, помеченных атрибутом как "делегат" (их даже не обязательно было наследовать от базового Delegate, достаточно было наследовать прямо от Object, а остальные ср-ва можно было бы получать от метакласса).
V>Плюсом было бы то, что загрузчик-верификатор мог бы эффективно "склеивать" попадающие под утиную типизацию такие функциональные типы, т.е. не засорять память копиями одного и того же бинарного кода!
V>Типов-делегатов ведь овердохрена, но уникальных сигнатур потенциально меньше.
V>Все эти Action<> и Func<>, таки, выглядят крайне ущербно — как попытка залатать исходно присутствующую дыру во фреймворке.
Все эти Action<> и Func<> как раз и являются реализацией ровно вашей же идеи путём повторного использования уже существующих компонентов инфраструктуры. То самое склеивание функциональных типов и всё такое.

V>1. На шаблонном уровне совместимы.

Шаблоны тоже не являются частью ООП-парадигмы. Вы критикуете решение, принятое в системе, где шаблонов не было, при этом указывая на систему, где аналогичная дыра заклеивается при помощи шаблона
V>2. Компилятор склеивает идентичный бинарный код различных типов.
Это вообще деталь реализации.

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

V>
V>bool Find<T>(ICollection<T> collection, bool predicate(T arg)) {...}
V>

Не понял, а в чём тут проблема?

V>Об костыли Action<> и Func<> мы спотыкаемся сразу же, когда речь идёт о модификаторах, например ref/in/out, а недавно еще появились scope и readonly.

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

V>Но утиная типизация или нет перпендикулярна статической типизации, прикинь? ))

Я в курсе.

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

V>Это появилось только с метаклассами в Смолтолке-80.
V>До этого никакой рефлексии не было.
Рефлексия ортогональна коду-как-данным. В лиспе есть код-как-данные, но рефлексии может и не быть.
В раннем дотнете рефлексия была, а кода-как-данных не было.
Код-как-данные — это Expression<T>. Рефлексия — System.Runtime.Reflection.

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

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

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

Конечно.

S>>В качестве упражнения можете попробовать спроектировать на С++ пару абстрактных классов — изменяемый вектор и immutable вектор. В терминах дотнета это были бы IImmutableList<T> и IList<T>. И посмотрите, можно ли их отнаследовать друг от друга; можно ли получить один из другого при помощи модификатора const; понадобится ли вообще модификатор const при проектировании этих классов или при их использовании.


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

Породить-то можете, а что вы с ним будете делать дальше?
Вы понимаете, что он будет нарушать спецификацию интерфейса?
V>2. В этой же технике в точности аналогично можно и в С++.
Ага. Осталось понять, при чём тут const, и устыдиться. Упражнение-то выполнить сможете?

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

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

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

Ну так для того, чтобы "мой" код корректно работал, мне нужны гарантии не только того, что я не изменяю объект, но и что никто другой его тоже не изменяет.
К примеру, когда этот развесистый словарь является ключом в другом словаре.

V>В целях эффективности в момент наполнения словарь может быть мутабельным, а потом в какой-то момент владение передаётся константной ссылке/указателю и ву а ля.

V>В отсутствии const в этом сценарии потребуется два типа — мутальный и иммутабельный, где готовый мутабельный словарь копируется в иммутабельный, с соответствующими накладными расходами и прессингом на память.
Фантазии, фантазии. Посмотрите, как устроен ImmutableDictionary в дотнете. Там нет const, и при этом "накладные расходы и прессинг на память" ровно такие же, как в вашем сценарии.

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

Ну нет конечно, недостаточно. С++ не даст мне гарантии, что кто-то не поменяет этот словарь после того, как я заложился на его неизменность.
Перед тем, как рассуждать об эффективности кода, нужно обеспечить его корректность.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Отредактировано 23.03.2023 2:21 Sinclair . Предыдущая версия .
Re[10]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 23.03.23 10:06
Оценка: -2
Здравствуйте, Sinclair, Вы писали:

V>>RTFM чего именно?

S>Истории Паскаля.

Да плевать конкретно на Паскаль, серьёзно.
Ни первый в плане P-кода, ни наиболее широко в реальных применениях его использовавший.


V>>Сам же привёл пример конкретной системы gemstone, т.е. имелась ввиду соответствующая инфраструктура в этой системе.

S>Инфраструктура построена на каких-то основах.

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


S>>>Ну, так как мне воспользоваться этим кодом изнутри VB?

V>>Языками более низкого уровня.
V>>Или расписать некий фреймворк оперирования памятью в некоей библиотеке и сделать импорт функций в VB (есть такая возможность), чтобы иметь требуемый инструментарий.
V>>Например, можно взять готовую либу CRT.
S>Давайте пример кода на VB, который при помощи готовой либы CRT отправляет пользовательский предикат на сервер для исполнения.

Тут ты потерял контекст, речь шла об произвольном управлении памятью, в т.ч. многопоточной (в VB можно задать тип аппартамента для компонент).
Показать как в VB делать импорт ф-ий из DLL?
Напомнить, что в VB есть модификатор ByRef, т.е. даже можно пользовать даже такие "железячные" примитивы как InterlockedIncrement и прочие из этой оперы.

Насчёт отправить код куда-то для исполнения — примеры приводил ниже: ActiveX компоненты в браузере.
Сколько их было написано именно на VB — одному богу известно. ))
Еще на VB легко запустить удалённую прогу (COM+) и общаться с ней, делая удалённые вызовы.


V>>Потому что в объектных файлах содержится код и данные со всей сопутствующей метаинформацией.

S>Это совершенно никак не связано с возможностями по манипуляции кодом как данными изнутри языка программирования.

Очень смелое или очень странное утверждение, на выбор. ))
Вот есть открытый проект llvm, в состав проекта входит ВСЯ функциональность оперирования над кодом виртуальной машинки, включая эмулятор этой машинки и JIT.
Есть фронтенды с разных языков, включая С++.
Народ подключает это в свои проекты и балуется:
https://habr.com/ru/company/timeweb/blog/572878/

Ну или можно взять открытый код WASM, ядро которого к браузеру нифига не привязано.


S>Я не понимаю, почему эта очевидная вещь до вас не доходит.


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


S>Компиляция в .obj была принята для практически 100% языков программирования; при этом возможностей мета-манипуляций в рантайме не было практически нигде.


В смысле? ))
Оперирование над obj-файлми — это свободно доступная библиотечная функциональность.

Я уверен, что поставь тебе такую задачу (отправлять код для исполнения на сервер) ты бы сегодня справился, пусть даже не с полутыка, бо в нейтиве не трудишься, но в итоге справился бы. И ответил бы сам себе на все эти вопросы по ходу решения задачи.

Лично я бы взял за основу для нейтива llvm или wasm, т.к. степень готовности к таким задачам там 100%.


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

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

Опиши ф-ии, оформи их в бинарный модуль, передай модуль на противоположную сторону (это может быть и сервером, и клиентом) с идентификатором вызываемой ф-ии или без идентификатора, если есть некие соглашения об именовании "Предиката" в модуле.
Ну и некая обвязка для кеширования модулей, их идентификации и версионности.

В древних COM+/ActiveX всё это есть.

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


V>>Я уже начинаю подозревать, что ты видишь возможность переносимости кода только в виде его AST-представления.

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

Конечно, такая возможность есть.
В чём проблема скомпилять бинарный модуль под llvm или wasm на С++ или Rust?


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


Это частности.
Под JS-Нодой можно прям исходники гонять туда-сюда.
(и всеми другими динамическими языками, в которых присутствует eval или его аналог)
Под джавой, дотнетом, llvm и wasm можно гонять скомпилённые бинарники абстрактной машинки.
Во времена засилья Windows в и-нете гоняли бинарники под архитектуру i386 в виде ActiveX.


S>Потому, что предикат не исполняется напрямую. СУБД на основе предиката строит план исполнения запроса, в котором одна часть предиката будет ключом поиска в индексе, другая будет фильтром по этому индексу, а третья будет вычисляться по связанной с индексом таблице. Это вам ликбез на пальцах.


Пфф, это не ликбез, это опущенное тобой условие конкретно этой задачи. ))
Я думал речь о чём-то навроде хранимок на .Net.

Достаточно было правильно сформулировать задачу: "Требуется именно AST выражения".
Это в разы более простая задача.

На том же Форт это решается через макросы — перехватывается вход и далее слова можно "записывать" в некую свою структуру.

На плюсах аналогичные решения есть в библиотеке Boost.Proto в связке с Boost.Mpl, Boost.Fusion и прочих библиотек для метапрограммирования.
В чём суть:
— есть некие плейсхолдеры (_, _1, _2 и т.д.) которые представляют из себя "начальные" типы с переопределёнными всеми операторами.
Каждый оператор порождает очередной узел AST, у которого так же переопределены все допустимые для данного типа узла операторы.

Выглядит это примерно так:
auto avg = (_1 + _2) / 2;

assert(avg(1, 3) == 2);

bool is_equal(double x, double y) {
    return std::fabs(x - y) < std::numeric_limits<double>::epsilon();
}

assert(is_equal(avg(5.0, 6.0), 5.5));


Получившееся значение (здесь переменная avg) — это аналог expression tree в дотнете.
Выражение может состоять из вложенных вызовов подобных ф-ий.
Есть биндинг, разумеется, в том числе частичный, т.е. весь аппарат функций высших порядков.

Это выражение может исполняться через operator(), т.е. просто вызываться как ф-ия с аргументами.
Выражение можно инспектировать с целью узнать структуру.
Останется вопрос сериализации и десериализации такого AST для передачи другой стороне.


S>Предикат, записанный в виде императивного байт-кода, таким преобразованиям поддаётся плохо либо никак.


Учись спрашивать.

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

Но у тебя их нет, путей отступления.
Их нет намного раньше, чем в дотнете появились expression tree, не знал? ))

Понятно, что ты был не в курсе, т.к. за другими технологиями особо не следишь...
Мог бы просто спросить "а как получить AST выражения в С++?", потому что "отправить удалённо" — это ненужный информационный шум к такой задаче.

Boost.Proto is a framework for building Embedded Domain-Specific Languages in C++.
It provides tools for constructing, type-checking, transforming and executing expression templates.

More specifically, Proto provides:
— An expression tree data structure.
— A mechanism for giving expressions additional behaviors and members.
— Operator overloads for building the tree from an expression.
— Utilities for defining the grammar to which an expression must conform.
— An extensible mechanism for immediately executing an expression template.
— An extensible set of tree transformations to apply to expression trees.

Отредактировано 23.03.2023 11:07 vdimas . Предыдущая версия .
Re[9]: понимание ООП Алана Кея
От: Ночной Смотрящий Россия  
Дата: 23.03.23 11:19
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Сам я впервые "вживую" курочил P-код в Бейсике ZX Spectrum.


Там не совсем тот P-код. Там просто упакованноое в удобное для интерпретации представление AST было, а в описываемых Паскалях это был машинный код виртуального CPU, как сейчас в Java и дотнете.

V>Паскаль под ZX Spectrum компилял в нейтив.

V>Паскали под IBM PC ходили борландовый и от MS, в P-код не компиллировали.

Ты по ссылке то немного дальше первой фразы почитай (английскую версию, русская как обычно)

Two early compilers generating p-code were the Pascal-P compiler in 1973, by Kesav V. Nori, Urs Ammann, Kathleen Jensen, Hans-Heinrich Nageli, and Christian Jacobi, and the Pascal-S compiler in 1975, by Niklaus Wirth.

... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[4]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 23.03.23 11:48
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Поэтому нет никакой проблемы, скажем, отправить блок кода на исполнение удалённому объекту — как это сделано в СУБД GemStone.


Минус за неточную формулировку.
Re[10]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 23.03.23 12:11
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>Там не совсем тот P-код. Там просто упакованноое в удобное для интерпретации представление AST было


Там коды "инструкций" Бейсика.
Просто инструкции высокоуровневые.


НС>а в описываемых Паскалях это был машинный код виртуального CPU, как сейчас в Java и дотнете.


Немного не понимаю, почему прицепились именно к Паскалю? ))
Технология впервые была использована в другом языке.
Широко использовалась и используется тоже в других языках.

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

V>Повторюсь, любой объектный файл (или архив их в объектной библиотеке) над переносимой платформой (например, llvm) представляет из себя то же самое.
V>Даже в Паскале, Си и С++.
V>К языку это перпендикулярно.
Сколько бы раз вы ни повторяли, это не перестанет быть заблуждением.


Я не согласен, ес-но.
Взять тот же С++, в нём рефлексия предоставляется некоторыми компиляторами — clang и одним из бранчей gcc.
Так же давно есть независимые фронтенды С++, которые дают на выходе AST.
Есть портируемые бэкенды llvm и wasm, а так же все либы по интроспекции объектных файлов.
Т.е. "вклиниться" в код можно на любой стадии, от AST до бинарных кодов, вопрос будет только в настройке тулчейна, где куда и что вклинивается у целевой системы на стадии разработки.

Спекулировать тут можно только насчёт того, что в том же дотнете рефлексия, ExpressionTree и Roslyn идут в базовой поставке и являются частью стандарта, а в С++ это дополнительный инструментарий, завязанный на конкретные реализации такого инструментария. Тут бы я не спорил, но дал бы ту информацию, что работа по стандартизации рефлексии в C++ давно идёт, ожидается в стандарте С++23.
Отредактировано 23.03.2023 12:31 vdimas . Предыдущая версия . Еще …
Отредактировано 23.03.2023 12:22 vdimas . Предыдущая версия .
Отредактировано 23.03.2023 12:12 vdimas . Предыдущая версия .
Re[5]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 23.03.23 12:36
Оценка:
Здравствуйте, Буравчик, Вы писали:

Б>А некоторые концепции так и не были повторены в других языках. Например, возможность изменять и сохранять состояние системы.


Впервые реализовано в Форте. ))


Б>Или возможность изменять все элементы системы — "системные библиотеки" и т.п.


Это более распространённая функциональность — хуки.
Является неотъемлимой частью загрузчиков современных операционок.
Re[11]: понимание ООП Алана Кея
От: Ночной Смотрящий Россия  
Дата: 23.03.23 13:02
Оценка: +1
Здравствуйте, vdimas, Вы писали:

НС>>Там не совсем тот P-код. Там просто упакованноое в удобное для интерпретации представление AST было

V>Там коды "инструкций" Бейсика.

Там коды ключевых слов. Причем организовано это строго как написано. А если посмотреть код "компилятора", то там простейший парсинг и просто подмена символов на их коды. Причем оригинал не сохраняется, а восстанавливается при необходимости по этому коду. Все. На Р-код это похоже исключительно в силу того, что на Р-код похож сам исходник того бейсика. Но смысл этого — сэкономить память на хранении программы и убрать из интерпретатора парсинг, а не обеспечить переносимость.

НС>>а в описываемых Паскалях это был машинный код виртуального CPU, как сейчас в Java и дотнете.

V>Немного не понимаю, почему прицепились именно к Паскалю? ))

Я же процитировал:

Two early compilers generating p-code were the Pascal-P compiler in 1973, by Kesav V. Nori, Urs Ammann, Kathleen Jensen, Hans-Heinrich Nageli, and Christian Jacobi, and the Pascal-S compiler in 1975, by Niklaus Wirth.


V>Технология впервые была использована в другом языке.


Было что то похожее. А в полноценном виде это были именно Паскали.

V>Мой поинт был в отделении понятия "язык программирования", как совокупности ситнаксиса и семантики от способа реализации этой семантики на стадии исполнения кода


И при этом ты привел в пример спектрумовский бейсик, в котором никакого отделения синтаксиса не было, был просто вынос стадии парсинга на этап сохранения строки в память.

V>Спекулировать тут можно только насчёт того, что в том же дотнете рефлексия, ExpressionTree и Roslyn идут в базовой поставке и являются частью стандарта, а в С++ это дополнительный инструментарий,


Вот именно. Нет ABI — все, куча сценариев закрывается.
Но вы тут опять с терминами устроили кашу, уж не знаю, случайно или намеренно. Р-код это непосредственно императивные инструкции и это отдельная песня. А rtti — это другая песня, хоть и упаковываетcя она в те же файлы. Зачем пытаться это все обсуждать одновременно — непонятно.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[10]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 23.03.23 15:11
Оценка:
Здравствуйте, Sinclair, Вы писали:

V>>Такие монстры как Голдберг служили неплохим противовесом этому, в общем-то, нубу-самоучке.

S>А что, Голдберг где-то заявляла, что язык Smalltalk был вдохновлён Фортом?

А что, Голдберг где-то заявляла, что язык Smalltalk был вдохновлён Лиспом?
Это ж чушь.
По официальной версии Smalltalk был вдохновлён Симулой, это повторяют участники разработки.

Из Форта взяли уже опробованные решения:
— шитый код, стековую машинку;
— возможность сохранения текущего состояния системы и повторной загрузки.

Последнее принципиально на медленной технике, это почему Форт порой был крайне удобен — каждый текущий момент времени ты компиллируешь/отлаживаешь только минимальный кусок кода.
Да, это была всего вторая в истории такая система после Форта.

Только в 3-й версии в Smalltalk-80 добавили вменяемую интроспекцию (а это уже языку 8 лет).
Отдалённо это можно сравнить с Лиспом и его расширением CLOS, потому что на деле нифига не так — в Лиспе хранится непосредственно AST в виде кортежей { функция, аргументы }.
А в Smalltalk код не хранится в таком виде.
Он хранится примерно как в Форте.
AST можно построить только обратной декомпиляцией, собсно, как это делается в Форт словом "see", куда я тебя уже отсылал, просто ты не понял — зачем. ))
Это примерно как обратная декомпиляция байткода CLI обратно в C#, только намного проще из-за простоты организации шитого кода.

Тебе же говорилось — ты слышал звон.


V>>Какой там в опу Лисп? ))

S>Да почитайте же уже The Early History of Smalltalk и перестаньте позориться.

Ты отвечай по-существу, не юли.
То, что сам Алан ретроспективно сравнивает свои решения с Лиспом и останавливается на отличиях — оно не делает ни тепло, ни холодно.
К тому же, он не единственный автор языка и его реализатор.


V>>Похоже, ты не трогал толком ни Смолтолк, ни Лисп, ни Форт, не понимаешь внутренней механики этих языков, но пытаешься фантазировать.

S>Вы всё время путаете дизайн языков с внутренней механикой компилятора и рантайма.

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

Я хорошо понимаю принятые в процессе разработки языка (и затем системы разработки на его основе) решения, а так же, откуда они взялись, где были уже обкатаны и доказали свою полезность/эффективность.


V>>Т.е. в изначальном Лиспе никаких метаклассов не было, как и не было в Лиспе ООП, ес-но, были только ф-ии как первоклассные объекты (сам код) и данные в виде однонаправленно связанных встроенных в систему списков.

S>Конечно не было. Именно это Кей и реализовал — ему хотелось сделать систему, которая была построена на минимуме примитивов, как Лисп, но с ООП. Если бы в Лиспе было ООП, то Smalltalk бы и не понадобился.

Понадобился бы.
Смолтолк намного эффективнее Лиспа, хотя и уступал нейтивно-компиллируемым языкам.
Смолтолк выразительнее Лиспа при описании ООП.
И вообще при описании банальных арифметических и логических выражений и просто императивного кода.
Уже этих двух аргументов достаточно, чтобы не воспринимать Лисп как удовлетворительную ООП-систему, хотя с ООП там более-менее в CLOS.

Просто надо понимать, как именно тогда использовался LISP.
Он был что-то вроде современного Питона, т.е. языком, на котором было легко обкатывать концепции, экспериментировать и т.д.

Я бы еще понял, если бы ты сформулировал "Смолтолк был вдохновлён недовольством Лиспом", бо это близко к истине.
И не только Лиспом, ес-но, просто Лисп — удобный мальчик для битья. ))


V>>Курить, что есть шитый код.

S>Я знаю, что такое шитый код. Какое отношение он имеет к дизайну языка Smalltalk?

Прямое.
Во главу угла изначально ставилась простота реализации.
Шитый код давал в разы лучшую эффективность, чем машинка Лиспа, всё еще позволяя удобно манипулировать бинарным кодом, порождать его "на лету" и т.д.

Дизайн языка не был сформирован чисто теоретически.
Это была рекурсивная разработка, где особенности реализации нижнего уровня влияли на верхние и обратно тоже.
Т.е. никто не пытался разработать совсем абстрактный язык, как в случае с тем же Паскалем-Обероном или Хаскелем.
Смолтолк — это изначально "реальный" язык. ))


V>>Пример развития Форта до переносимости м/у устройствами.

S>По-прежнему не понимаю, какое отношение Постскрипт с его переносимостью имеет к ООП Алана Кея.

Это уже юление.
Ты говорил про переносимость кода тут.
Хотя на самом деле имел ввиду не это.
(или же намеренно оставил как "последний аргумент", хотя я несколько раз явно дал понять, как понял твою задачу).


V>>Таки, самообразованием принято заниматься самостоятельно, не испытывая терпение коллег.

S>Ну так займитесь. Почему вы вместо того, чтобы почитать первоисточники, занимаетесь гаданием на МК-51?

Алан Кей с его столь громкими и столь же некорректными высказываниями не заслуживает достаточного доверия в кач-ве надёжного источника.
Над языком работали еще люди.
Пробуй аргументировать другими авторами, если сможешь.

— Аллан не изобрел ООП (хотя позиционирует себя как автор ООП).
— В его формулировке ООП неполно: http://www.rsdn.org/forum/flame.comp/8471966.1
— Он не изобрел ни одного принципиального решения, легшего в основу Смолтолка.

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

Он, по-сути, "интегратор-компилятор" — увидел возможность реализации полудинамического ООП-языка с достаточной эффективностью на основе имеющихся уже в IT на тот момент наработок.
До Смолтолка ООП-языки были только статическими (библиотечная эмуляция ООП на Лиспе не в счёт, бо эмулировать можно что угодно на чём угодно).
Он предложил создать систему с такими св-вами, пообещав, что реализация должна получиться простой, всё.
Но работали они над языком аж 8 лет, прежде чем продукт стал коммерческим.
Т.е. не всё так просто, и тут очередная саечка Алану за шапкозакидательство.
(я вообще терпеть не могу поверхностных людей, особенно в инженерии)

Это что-то типа проекта Nemerle — ни одной новой концепции в языке не изобрели, просто попытка собрать удачные концепции на удачной платформе.
Но! Nemerle реализовали достаточно быстро в первой версии и достаточно полно, в отличие от.
И описание концепций Nemerle удивительно точное и полное.

Я не могу на полном серьёзе сравнивать болтовню Алана уровня болтовни бабушек у подъезда с подачей материала другими авторами.
Есть еще один такой же прихлебатель от IT — Мартин Фаулер, с Аланом два сапога пара.
Якающие нубы, за которых сплошной испанский стыд. ))


S>>>Попробуйте реализовать на Паскале, Си, и С++ функцию, которая бы передавала пользовательский предикат на сервер для исполнения.

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

В предыдущем сообщении пример дан.


V>>Напомню, что MS компилятор С++ умеет компиллировать unamanaged C++ код (т.е. безо-всяких managed расширений) в чистый байт-код.

V>>(тип генерируемого образа для режима С++/CLI задаётся опциями компилятора)
S>Ну ок, если вам будет проще — попробуйте изобразить требуемую функциональность на unmanaged C++, скомпилированном в чистый байт-код.

Точную форулировку требуемой функциональности в студию.


V>>Ну вот попробуй на Лисп (или другом динамическом языке) без динамического исполнения текстовых исходников, а я поржу.

S> Посмотрите на то, как устроены макросы Лиспа. Там нет ничего про динамическое исполнение текстовых исходников.
S>Всё построено на манипуляциях кодом в виде AST. Можете начинать ржать.

Это залёт, курсант! ))
Код макросов лиспа не манипулирует AST явно.
Макросы Лиспа подстановочные (шаблонные), как макросы Си/С++ или макроассемблера.
Заметное отличие лишь в том, что макросы Лиспа МОГУТ быть гигиеническими (если программист не забудет экранировать область видимости символов, бгг).

А вот макросы Форта устроены иначе — они получают на входе поток лексем и манипулируют с ним именно явно, порождая то самое AST.
Смотри, сколько каши приходится разгребать. ))


V>>Такая возможность связана с представлением исполняемого кода, а это представление перпендикулярно языку.

V>>Похоже, у тебя каша в голове из св-в языков и конкретных их компиляторов/интерпретаторов.
S>Всё ровно наоборот — это у вас каша.

У меня понимание, как оно устроено и работает.
А у тебя бесконечные "слышал звон" и передёргивания из разряда сказала-мазала.


V>>Язык, по-сути, тот же.

V>>Отличается представлением скомпиллированного кода, а значит, особенностями модели вычисления.
S>И самое замечательное, что эти особенности модели вычисления никак не влияют на то, о чём я говорю.

Еще как влияют.
Макросы Схемы живут только в момент компиляции, в отличии от макросов Лиспа, которые становятся частью текущего состояния "системы".
Макросы Схемы имеют другое ключевое слово и пару особенностей.
Но это по-прежнему подстановочные/позиционные макросы, без явного манипулирования AST.


S>Макросы в Схеме всё ещё есть, и это означает, что я могу решить обозначенную задачу и на схеме тоже.


Увы, увы.

Причём, тут я противоречу самому себе, вроде бы, ведь можно представить себе такую реализацию Схемы, которая ведёт себя как Лисп?
Представить такую реализацию можно, да вот только Схема — это именно компиллируемая версия Лиспа. ))
А динамическая версия — это сам Лисп.

Для целей эффективного конечного кода пришлось внести в Лисп несколько ограничений, наверно поэтому назвали другим языком и стандарты Схемы с тех пор развиваются независимо от Лиспа.
Вернее, впервые стандарты на семейство Лисп появились в Схеме — именно из-за вносимых ограничений.
Заметно позже сообщество стало формировать стандарты и на Лисп — CL.
Ну и, стандарты на эмуляцию ООП в Лиспе поверх CL — CLOS.

Хотя именно с точки зрения языка (а не подробностей его реализации) Схему можно считать диалектом Лиспа, конечно!


S>А всё потому, что решают тут свойства языка. Что там под капотом — дело десятое.


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

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


V>>Не осенило еще? ))

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

Сделать что именно?
Учись спрашивать.


V>>Например, MS Visual Basic for DOS компиллировал в неплохо оптимизированный код (я курочил дизассемблером что он там порождает — да там офигенно, на уровне их же компилятора Си и Паскаля).

S>Да видел конечно. Толку-то? Ни на одном из этих бейсиков я не могу отправить на сервер код пользовательского предиката.

Это был наглядный пример того, что язык тот же, а реализация разная.
В офисе он же хранится в виде VBA, и документ можно отослать и исполнить код в нём.


V>>В Лисп точно так же может сосуществовать сколько угодно много независимых ООП-подсистем библиотечного уровня.

S>Я в курсе. Синтаксис Лиспа настолько ужасен, что его ничем испортить нельзя. Поэтому всякие надстройки над ним выглядят не хуже оригинального лиспа.
S>И можно делать любое ООП, которое нравится — с наследованием интерфейсов и наследованием реализации, со множественным наследованием и без, с любыми наборами модификаторов "видимости" мемберов. Можно придумывать свойства и события; можно делать наследование экземпляров как в JS; можно обрабатывать неизвестные сообщения, как в Smalltalk.
S>Правда, всё это будет всё в том же ужасном стиле скобок поверх скобок. Но на фоне остального лисп-кода выделяться не будет.

В любом случае, это лишь эмуляция.
А эмулировать что угодно можно на любом Тьюринг-полном языке.
Объекты в Лиспе не являются первоклассными сущностями языка, вот в чём косяк.
Первоклассной сущностью там являются числа/символы, функции и пара CONS(car, cdr), где каждый элемент пары может быть числом, функцией или опять парой (ссылочная семантика для всего перечисленного).


S>В общем, Лисп считать ОО-языком бессмысленно.


Именно.
Зато Форт (бгг, сорри... Но Чарльз Мур был, таки, умнейшим челом) позволяет сделать первоклассной сущностью любую хрень.
Форт рассматривается опытным фортером как язык для порождения языков (из-за особенностей макросистемы, которая нифига не как в Лиспе), и именно так пишутся на ём программы — исключительно через определение слоёв DSL от самых низких до целевых. Не зря конструкции Форта называются словами. Программа в форте — это всегда описание новых слов. А с помощью них — других, более ёмких.

ничего более элегантного я не видел до сих пор, т.к. виденные другие языки навязывают синтаксис и философию.
Форт навязывает лишь способ мышления, не навязывая остального.
И при этом чудовищно прост в реализации.
И при этом чудовищно эффективен, в сравнении с Лиспом.
Порой и в сравнении с нейтивом из-за особенностей манипулирования стеком — в Форте обычно меньше паразитных манипуляций данными в стеках/регистрах, меньше ненужных копирований/преобразований данных — состояние стека на выходе одного слова часто является готовым состоянием стека для вызова другого. Писать программы на Форте — это как играть в Тетрис, натурально, все фигуры должны стыковаться, и тогда прога просто летает. ))


V>>Ты не понимаешь мотива принятия некоторых важных решений в IT в ретроспективе.

S>

Более того, ты зачем-то отмахиваешься от такой инфрмации, оперируя вещами, скорее, эмоциональными, чем рациональными.


V>>Проводимый ликбез тебя коробит, но это особенности твоего чванства и ничего более.

S>Скорее, это особенности вашего чванства.

За новую инфу я всегда благодарен, в отличие от.
А тебя аналогичный сценарий всегда бесит, что ты аж перестаёшь быть корректным в логике спора. ))
Отредактировано 23.03.2023 21:43 vdimas . Предыдущая версия . Еще …
Отредактировано 23.03.2023 21:35 vdimas . Предыдущая версия .
Отредактировано 23.03.2023 15:34 vdimas . Предыдущая версия .
Отредактировано 23.03.2023 15:26 vdimas . Предыдущая версия .
Отредактировано 23.03.2023 15:23 vdimas . Предыдущая версия .
Отредактировано 23.03.2023 15:21 vdimas . Предыдущая версия .
Отредактировано 23.03.2023 15:14 vdimas . Предыдущая версия .
Re[10]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 24.03.23 09:42
Оценка: :)
Здравствуйте, 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> не обеспечивает ни необходимости, ни достаточности.

Поэтому твои вопросы насчёт "где мне взять уверенность" могли бы относиться к дотнету, но никак ни к С++, бо там эту уверенность при надобности обеспечить можно — все средства для этого есть, велкам!
А в дотнете — дудки!
Отредактировано 27.03.2023 11:31 vdimas . Предыдущая версия . Еще …
Отредактировано 24.03.2023 11:42 vdimas . Предыдущая версия .
Отредактировано 24.03.2023 9:52 vdimas . Предыдущая версия .
Отредактировано 24.03.2023 9:51 vdimas . Предыдущая версия .
Отредактировано 24.03.2023 9:50 vdimas . Предыдущая версия .
Отредактировано 24.03.2023 9:48 vdimas . Предыдущая версия .
Отредактировано 24.03.2023 9:46 vdimas . Предыдущая версия .
Отредактировано 24.03.2023 9:43 vdimas . Предыдущая версия .
Re[11]: понимание ООП Алана Кея
От: Ночной Смотрящий Россия  
Дата: 24.03.23 11:44
Оценка: +1
Здравствуйте, vdimas, Вы писали:

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

V>И как же Reflector работал? ))

Фигово. Делать на основе этого решения, не связанные с реверс-инжинирингом было невозможно.

V>А всякие AOP-ориентированные расширения?


А это вообще не про код как данные.

V>При наличии взаимно-однозначного отображения кода на AST


Не было такого. Очень похоже — да, но 100% точности не было.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[12]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 24.03.23 12:02
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

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

V>>И как же Reflector работал? ))
НС>Фигово. Делать на основе этого решения, не связанные с реверс-инжинирингом было невозможно.

Фиговость проистекает из очевидного — CLI-машинка разрабатывалась не как привязанная конкретно к языку C#.
Если бы привязанность была, было бы меньше допущений, меньше инструкций (часть из них были бы более высокоуровневые), существовало бы однозначное отображение байт-кода на C#.
А так-то, разумеется, можно породить такой байт-код, который не маппится на валидный C#.
Это был просто пример, который показывает суть — не всегда требуется хранить граф AST в явном виде.


V>>А всякие AOP-ориентированные расширения?

НС>А это вообще не про код как данные.

Однако, они работали уже над бинарным кодом когда-то до Рослина. ))


V>>При наличии взаимно-однозначного отображения кода на AST

НС>Не было такого. Очень похоже — да, но 100% точности не было.

Мы тут о Смолтолке рассуждали и вообще о стековых машинках.
Просто стековые машинки дотнета и джавы не являются функционально-чистыми стековыми машинками — в них выделение ячеек стека может происходить без инициализации ячеек, то бишь, в стек кладутся не результаты вычислений, а просто может быть зарезервировано место. Такие операции относятся к "служебным", явно в код не отображаются, могли бы обыгрываться уже на уровне JIT... Просто тогда JIT вынужден был бы отжирать больше ресурсов, в общем, сплошные компромисс на компромиссе. ))

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

И еще момент, походу, Синклер упустил важное — для передачи графа-AST "куда-то" (именно графа) его надо сериализовать и затем десериализовать.

В случае стековой машинки код уже хранится как сериализованный, т.е. это его естественное представление.
Соответственно, ни стадии сериализации (как разрушения "объемной структуры"), ни стадии десериализации (как восстановления этой структуры) не требовалось.

Т.е., в случае стековой машинки трасформацию графа AST можно выполнять прямо над сериализованным представлением.
Собсно, именно так и работает бета-редукция в функциональных языках.
Отредактировано 24.03.2023 14:14 vdimas . Предыдущая версия . Еще …
Отредактировано 24.03.2023 12:03 vdimas . Предыдущая версия .
Re[13]: понимание ООП Алана Кея
От: Ночной Смотрящий Россия  
Дата: 24.03.23 12:10
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Фиговость проистекает из очевидного — CLI-машинка разрабатывалась не как привязанная конкретно к языку C#.


Что это меняет в контексте разговора?

V>Если бы привязанность была,


Если бы у бабушки ...

V>Это был просто пример, который показывает суть — не всегда требуется хранить граф AST в явном виде.


Пример чего? Тебе вроде бы сказали простую вещь — либо в платформе код как данные это first class citizen, либо нет. Никакой рефлектор на это не влияет, и пример твой какой то нерелевантный совсем.

V>>>А всякие AOP-ориентированные расширения?

НС>>А это вообще не про код как данные.
V>Однако, они работали уже над бинарным кодом когда-то до Рослина. ))

См. выше.

Бла-бла-бла не по теме скипнуто.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[10]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 24.03.23 12:34
Оценка:
Здравствуйте, Sinclair, Вы писали:

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


Вдогонку, паттер Wrapper (Decorator) никто не отменял.
Оберни нужный тип по-значению (абстракции в С++ бесплатны, угу), опиши оборачиваемое значение как константное поле типа (т.е. инициализируемое только в конструкторе), опиши соотв. делегирующие const-методы.
Конструктор объяви перемещающим, чтобы гарантировать отсутствие немутабельных внешних ссылок на владеемые тобой данные.
Сделать это можно однократно в несколько строк в шаблонном виде, что для типа-ключа, что для словаря целиком.
Такая система ограничений будет работать с любым объектом, удовлетворяющим публичному интерфейсу std::map (их даже изкаробки идёт уже несколько).
Свой шаблонный код опиши уже в концептах и будет тебе железобетонная уверенность. ))

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

Если тебе интересно закрыть эту тему раз и навсегда — распишу весь код целиком.
Отредактировано 24.03.2023 13:46 vdimas . Предыдущая версия .
Re[14]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 24.03.23 12:50
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

V>>Фиговость проистекает из очевидного — CLI-машинка разрабатывалась не как привязанная конкретно к языку C#.

НС>Что это меняет в контексте разговора?

Ничего.
Твоё замечание о конкретике было верным, но мой пример как более общий тоже неплохо работает.


V>>Если бы привязанность была,

НС>Если бы у бабушки ...

Конкретика, конкретика...
Я отсылал коллегу к хорошо ему знакомому.
Мне этот пример не требовался.


V>>Это был просто пример, который показывает суть — не всегда требуется хранить граф AST в явном виде.

НС>Пример чего? Тебе вроде бы сказали простую вещь — либо в платформе код как данные это first class citizen, либо нет.

Expression<T> и его наследники не являются first class citizen.
С т.з. языка это "пользовательские типы данных".
В общем, требование first class citizen надуманное.
Рассуждать можно лишь о наличии такой реализации или нет.
Или о наличии нескольких реализаций.
Тебе никто не запретит расписать свою независимую иерархию-аналог, вклинившись через Рослин в компиляцию.

Вдогонку, first class citizen имеют неизвестную с т.з. языка структуру.
В том же Лиспе можно получить тело ф-ии в виде списка, но нельзя понять, как эта ф-ия на самом деле устроена унутре на уровне машинки.
А там не только тело, это специальная системная запись-символ.
Структура символа неизвестна.

Как пример — строки или делегаты в дотнете.
Имеют неизвестную с т.з. языка внутреннюю структуру.


НС>Бла-бла-бла не по теме скипнуто.


Смотря какая тема.
Если тема конкретно байт-кода дотнета — то в контексте обсуждения не принципиально.
При завязке только на C#, байт-код дотнета мог бы состоять только из помещения значений и литералов на стек и вызовов ф-ий (методов).
Это было бы точное сериализованное представление AST, взаимно однозначное с его представлением в виде графа.

Зацепились-то за "явное представление" AST.
Пахнуло дотнетом, угу. ))

А на деле, например, при компиляции функциональных языков граф вычислений никогда не живёт в памяти целиком, просто потому что этого не требуется.
Я не раз уже обращал внимание твоё, Влада2 и Вольфхаунда, что в промышленных решениях чаще используют оперативную обработку графов, вместо сливания в бутылочное горлышко и разливание затем обратно. Даже в случае ленивых языков, цепочка бета-редукции работает именно над стековой машинкой и её итерирование происходит как показал картинкой последовательность обхода графа — т.е. в сериализованном виде. При оперативной обработке граф живёт только в голове разработчика, никогда не занимая память на все свои развесистые связи целиком, где стоимость хранения связей порой выше стоимости хранения целевых данных. ))
Отредактировано 24.03.2023 13:02 vdimas . Предыдущая версия . Еще …
Отредактировано 24.03.2023 12:58 vdimas . Предыдущая версия .
Re[15]: понимание ООП Алана Кея
От: Ночной Смотрящий Россия  
Дата: 24.03.23 17:47
Оценка: :)
Здравствуйте, vdimas, Вы писали:

НС>>Пример чего? Тебе вроде бы сказали простую вещь — либо в платформе код как данные это first class citizen, либо нет.

V>Expression<T> и его наследники не являются first class citizen.

В языке C# — являются.

V>С т.з. языка это "пользовательские типы данных".


Ты сейчас глупость написал.

V>Вдогонку, first class citizen имеют неизвестную с т.з. языка структуру.


И что? Они имеют известные с точки зрения языка название типа и имена и сигнатуры его статических методов. Это намертво прошито в компилятор. И именно проэтому это first class citizen.

Бла-бла-бла не по теме скипнуто.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[16]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 25.03.23 02:36
Оценка:
Здравствуйте, Ночной Смотрящий, Вы писали:

НС>>>Пример чего? Тебе вроде бы сказали простую вещь — либо в платформе код как данные это first class citizen, либо нет.

V>>Expression<T> и его наследники не являются first class citizen.
НС>В языке C# — являются.

Только в том смысле, что наследуются от Object, который first class citizen.
Так можно про любой GC-тип дотнета сказать. ))


V>>С т.з. языка это "пользовательские типы данных".

НС>Ты сейчас глупость написал.

Ты сейчас фейсом об тейбл.

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

Граф Expression<T> прекрасно можно построить и ручками.


V>>Вдогонку, first class citizen имеют неизвестную с т.з. языка структуру.

НС>И что?

И всё.
Пользовательские типы имеют известную в терминах языка структуру.
И эта структура разлагается аккурат до атомарных первоклассных сущностей языка.


НС>Они имеют известные с точки зрения языка название типа и имена и сигнатуры его статических методов. Это намертво прошито в компилятор.

НС>И именно проэтому это first class citizen.

Сова треснула. ))
Сия агрессивная упёртость и глупый спор с базовыми вещами, которые тебе преподавали еще в ВУЗ-е, попахивают попыткой оправдать обосратушки со сроками выхода Рослина, что пришлось намертво вшивать в язык конверсию AST в Expression<T> для целей скорейшего выпуска EF и LINQ без Roslyn когда-то.

Вот я определил свой тип MyExpression, открыл в инете примеры по Рослин и за 10 минут борьбы с незнакомой предметной областью получил примерно в таком генераторе:
[Generator]
internal class MyExpressionGenerator : ISourceGenerator { 
    public void Execute(GeneratorExecutionContext context) {
        ...
        var lambdasToRewrite = tree.GetRoot()
                .DescendantNodes()
                .OfType<LambdaExpressionSyntax>()
                .Where(l => model.GetTypeInfo(l).ConvertedType?.Name == "MyExpression")
                .ToList();
        ...

список AST-узлов всех лямбд, из которых пытался получить MyExpression.
Далее дело техники — конвертировать подробное AST Рослина в упрощенное AST моего MyExpression.

Так шта, ребят, не надо ссать нам в уши, как грится...

В дотнете и C# слишком много косяков, которые случились "потому что так вышло" (С), пополняя груз "проклятого легаси". ))
Делать из этого какие-то выводы или, упаси боже, ссылаться на косяки как на аргументы — дело заведомо дохлое.

Тот факт, что обсуждаемый Смолтолк разрабатывали 8 лет прежде чем показать народу — оно развязывало разработчикам руки, позволяло избавляться от ошибочных решений.
Дотнет же тянет с собой много чего ненужного, еще аж кучу нетипизированного бреда с первых версий без генериков, потому что выкинуть весь этот бред никак от слова совсем — вся индустрия уже обмазалась.

Expression<T> — такой же точно бред, как нетипизированная стандартная библиотека первых версий дотнета.

Потому что надо давать возможность трансформации любого кода через полноценное AST исходника, и тогда это можно рассматривать как эдакую навороченную макросистему+кодогенерацию в языке, как оно есть сейчас, а не лепить убогий костыль на некий выделенный сценарий...
Хотя, когда происходит ситуация "бизнес требует, а мы не успеваем", чего только может ни случиться...
Отредактировано 25.03.2023 2:49 vdimas . Предыдущая версия . Еще …
Отредактировано 25.03.2023 2:48 vdimas . Предыдущая версия .
Отредактировано 25.03.2023 2:47 vdimas . Предыдущая версия .
Отредактировано 25.03.2023 2:38 vdimas . Предыдущая версия .
Отредактировано 25.03.2023 2:38 vdimas . Предыдущая версия .
Re[17]: понимание ООП Алана Кея
От: Ночной Смотрящий Россия  
Дата: 25.03.23 13:21
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Граф Expression<T> прекрасно можно построить и ручками.


Ручками — можно, а чтобы компилятор за тебя собрал — нельзя.

НС>>Они имеют известные с точки зрения языка название типа и имена и сигнатуры его статических методов. Это намертво прошито в компилятор.

НС>>И именно проэтому это first class citizen.
V>Сова треснула. ))
V>Сия агрессивная упёртость

Ну ты и чудак на букву М. Пытаешься с тобой общаться как с человеком, а ты как подзаборная пьянь отвечаешь. Адьос.
... << RSDN@Home 1.3.17 alpha 5 rev. 62>>
Re[18]: понимание ООП Алана Кея
От: vdimas Россия  
Дата: 26.03.23 15:35
Оценка: -2
Здравствуйте, Ночной Смотрящий, Вы писали:

V>>Граф Expression<T> прекрасно можно построить и ручками.

НС>Ручками — можно,

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


НС>а чтобы компилятор за тебя собрал — нельзя.


Раньше было нельзя, до Roslyn.
Сейчас можно.


V>>Сия агрессивная упёртость

НС>Ну ты и чудак на букву М. Пытаешься с тобой общаться как с человеком, а ты как подзаборная пьянь отвечаешь. Адьос.

Чьяб корова мычала со своим хамством:

V>>С т.з. языка это "пользовательские типы данных".
НС>Ты сейчас глупость написал.

Я помню, на какой специальности ты учился, значит определения знаешь.
Моё утверждение — это даже не утверждение, а напоминание определений из самой базы ЯВУ.

Да и не в этом дело — я тебе показал как работать со своим произвольным MyExpresison, т.е. порождать своё AST из лямбд через Roslyn, что множит твою агрессивную упёртость на ноль.
Отредактировано 26.03.2023 15:42 vdimas . Предыдущая версия . Еще …
Отредактировано 26.03.2023 15:38 vdimas . Предыдущая версия .
Re[11]: понимание ООП Алана Кея
От: korvin_  
Дата: 26.03.23 20:19
Оценка:
Здравствуйте, vdimas, Вы писали:

V>Код макросов лиспа не манипулирует AST явно.

V>Макросы Лиспа подстановочные (шаблонные), как макросы Си/С++ или макроассемблера.

С чего это вдруг?

V>А вот макросы Форта устроены иначе — они получают на входе поток лексем и манипулируют с ним именно явно, порождая то самое AST.


Макросы Лиспа получают на вход дерево объектов и манипулируют с ним явно. В чём отличие?

V>Макросы Схемы живут только в момент компиляции, в отличии от макросов Лиспа


Что мешает в Схеме вызвать eval в рантайме?

V>Макросы Схемы имеют другое ключевое слово


Это существенное отличие, да.

V>и пару особенностей.


Каких?

V>Но это по-прежнему подстановочные/позиционные макросы, без явного манипулирования AST.


Что мешает работать с syntax object в Схеме через syntax-case, например?

V>Причём, тут я противоречу самому себе, вроде бы, ведь можно представить себе такую реализацию Схемы, которая ведёт себя как Лисп?

V>Представить такую реализацию можно, да вот только Схема — это именно компиллируемая версия Лиспа. ))
V>А динамическая версия — это сам Лисп.

SBCL прекрасно компилирует Common Lisp. А eval из Схемы никуда не делся.

V>Для целей эффективного конечного кода пришлось внести в Лисп несколько ограничений, наверно поэтому назвали другим языком и стандарты Схемы с тех пор развиваются независимо от Лиспа.


Схема не так и не для этого разрабатывалась.

V>Вернее, впервые стандарты на семейство Лисп появились в Схеме — именно из-за вносимых ограничений.


С чего ты взял, что из-за них?

V>В любом случае, это лишь эмуляция.


Чем здесь эмуляция отличается от «не-эмуляции»?

V>Объекты в Лиспе не являются первоклассными сущностями языка, вот в чём косяк.


Являются.

V>Первоклассной сущностью там являются числа/символы, функции и пара CONS(car, cdr), где каждый элемент пары может быть числом, функцией или опять парой (ссылочная семантика для всего перечисленного).


И много что ещё. Перечитай определение, что такое first-class citizen.

V>Форт навязывает лишь способ мышления, не навязывая остального.

V>И при этом чудовищно прост в реализации.
V>И при этом чудовищно эффективен, в сравнении с Лиспом.
V>Порой и в сравнении с нейтивом из-за особенностей манипулирования стеком — в Форте обычно меньше паразитных манипуляций данными в стеках/регистрах, меньше ненужных копирований/преобразований данных — состояние стека на выходе одного слова часто является готовым состоянием стека для вызова другого. Писать программы на Форте — это как играть в Тетрис, натурально, все фигуры должны стыковаться, и тогда прога просто летает. ))

А уж ассемблер-то как эффективен. И что из этого вытекает? Зачем все эти Лиспы, Си, Паскали и прочие Форты понапридумывали?
Re[15]: понимание ООП Алана Кея
От: korvin_  
Дата: 26.03.23 20:25
Оценка: +2
Здравствуйте, vdimas, Вы писали:

V>Expression<T> и его наследники не являются first class citizen.

V>С т.з. языка это "пользовательские типы данных".
V>В общем, требование first class citizen надуманное.

First-class citizen и built-in — ортогональные вещи.

First-class citizen — это:

Robin Popplestone gave the following definition: All items have certain fundamental rights.

All items can be the actual parameters of functions
All items can be returned as results of functions
All items can be the subject of assignment statements
All items can be tested for equality.

последний пункт неоднозначный, но «пользовательские/встроенные типы данных» тут совершенно не при чём.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.