Re[2]: Недоучки по настоящему ООП не освоили (из-за Basic и С++)
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.09.25 08:42
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Я не очень понимаю. Если назвать вызов метода отправкой сообщения объекту, которому принадлежит метод, на что это вообще по сути влияет?

Конкретно это влияет на то, каким образом происходит обработка сообщений.
Если считать, что вызов метода — это просто вызов функции со специальной подстановкой аргументов (a->b(c) === a->vmt[__b](a, c)), то даже вопроса "а как обработать вызов несуществующего метода" не возникает.

А если считать, что вызов — это отправка сообщений, то сразу понятно, что диспетчеризация будет на стороне получателя. И он, в частности, может выбрать обрабатывать все сообщения одним куском кода, а может как-то фильтровать их и обрабатывать разными кусками кода.

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

Хотя более центральной идеей в ST является не "отправка сообщений", а homoiconicity — то, что вообще всё является объектами.
В той же джаве сделан реверанс в сторону "машинных типов", поэтому там есть примитивные типы. А в смолтоке — нету, и числа там — точно такие же объекты, как и всё остальное.
Поэтому, когда мы прибавляем к иксу игрек, мы отправляем ему сообщение "увеличить" c аргументом игрек; в ответном сообщении нам икс возвращает (возможно новый) объект-число, значение которого равно сумме икса и игрека.
Тогда у нас в принципе не возникает проблем вроде того, что "массив int — это одно, а массив BigDecimal — это совсем другое". Можно написать свой класс чисел, и он будет полностью взаимозаменяем с "обычными интами".

В том числе и в вопросах оборачиваемости его проксями, когда можно это число хранить на другой машине и вся арифметика будет происходить там.

И код представлен точно такими же объектами, как и "данные". Поэтому мы можем отправить объекту кусок кода и попросить с этим кодом что-нибудь сделать.
Именно так работает условное выполнение в смолтоке: там нет инструкции if, а есть булевые объекты, которым передаются сообщения с кодом, который нужно выполнить в зависимости от значения объекта.

И именно так сделано выполнение запросов в их ООСУБД Gemstone: код запроса уезжает на сервер и исполняется там, а обратно приезжают результаты.
Все эти вещи — охренительно круты концептуально, особенно с учётом того, что это работало сорок лет тому назад.
Несмотря на то, что сам по себе этот язык можно считать мёртвым, но его влияние на индустрию — колоссально.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[3]: Недоучки по настоящему ООП не освоили (из-за Basic и С++)
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.09.25 09:04
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>А если считать, что вызов — это отправка сообщений, то сразу понятно, что диспетчеризация будет на стороне получателя. И он, в частности, может выбрать обрабатывать все сообщения одним куском кода, а может как-то фильтровать их и обрабатывать разными кусками кода.


А это не то же самое, что иметь возможность определить дефолтовый метод, который вызывается, когда нет подходящего конкретного метода?

И, очевидное обобщение, относиться к набору конкретных методов как к такому pattern-matching с возможностью добавить pattern, который матчит всё, если не нашлось варианта получше...

S>Хотя более центральной идеей в ST является не "отправка сообщений", а homoiconicity — то, что вообще всё является объектами.

S>В той же джаве сделан реверанс в сторону "машинных типов", поэтому там есть примитивные типы. А в смолтоке — нету, и числа там — точно такие же объекты, как и всё остальное.

Вот между прочим в Go зашли чуть с другой стороны.

Там любой тип может иметь методы.

type MyInt int // Пользовательский тип, сделаный из int

// И приделали к нему метод.
func (i *MyInt) Inc() {
  (*i) ++
}


И это тоже как бы сглаживает разницу между примитивными и пользовательскими типами.

Единственное что, встроенные операции, типа +, — и т.п. работают с типами, которые основаны на базовых типах, для которых эти операции определены (т.е., с типом MyInt, как выше, работать будут), а вот со структурами всякими работать не будут. Поэтому для двух big.Int не напишешь a + b.

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

S>Все эти вещи — охренительно круты концептуально, особенно с учётом того, что это работало сорок лет тому назад.


Так все концептуально крутые вещи лет 40-50 назад и придуманы. Кроме, может, алгоритма RSA и системы типов Хиндли-Милнера

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


Тут напрашивается сравнение с LISP. Он ведь тоже такой, все запчасти нараспашку. Код документированным (и довольно внятным) образом является данными, хочешь — исполняй, хочешь во что-то другое перерабатывай.
Re[4]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: korvin_  
Дата: 03.09.25 09:25
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>А это не то же самое, что иметь возможность определить дефолтовый метод, который вызывается, когда нет подходящего конкретного метода?


Могло бы быть похоже, если бы так можно было сделать. В C++, Java, C# так сделать нельзя.

Ну и остаётся непокрытой возможность переслать сообщению другому объекту.

Pzz>Так все концептуально крутые вещи лет 40-50 назад и придуманы. Кроме, может, алгоритма RSA и системы типов Хиндли-Милнера


Типизации по Хиндли-Милнеру тоже уже лет под 40-50.

The origin is the type inference algorithm for the simply typed lambda calculus that was devised by Haskell Curry and Robert Feys in 1958.

In 1969, J. Roger Hindley extended this work and proved that their algorithm always inferred the most general type.

In 1978, Robin Milner, independently of Hindley's work, provided an equivalent algorithm, Algorithm W.


-- Wiki
Отредактировано 03.09.2025 9:27 korvin_ . Предыдущая версия .
Re[5]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.09.25 09:29
Оценка:
Здравствуйте, korvin_, Вы писали:

Pzz>>Так все концептуально крутые вещи лет 40-50 назад и придуманы. Кроме, может, алгоритма RSA и системы типов Хиндли-Милнера


_>Типизации по Хиндли-Милнеру тоже уже лет под 40-50.


Как быстро время-то летит...
Re[5]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: Hоmunculus  
Дата: 03.09.25 10:09
Оценка:
Здравствуйте, Shmj, Вы писали:

S>Я уважаю недоучек, еще больше уважаю людей не учившихся в школе.


Сына своего в школу не будешь отдавать?
Re[4]: Недоучки по настоящему ООП не освоили (из-за Basic и С++)
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.09.25 10:30
Оценка:
Здравствуйте, Pzz, Вы писали:
Pzz>А это не то же самое, что иметь возможность определить дефолтовый метод, который вызывается, когда нет подходящего конкретного метода?
Это когда мы совершили полный круг и вернулись к идее частичной диспетчеризации в компайл-тайме, но уже с учётом накопленных "идей".
Ведь ни в Object Pascal, ни в C++ ничего подобного нет, и никогда в голову не приходило.
Тем более, что пока мы мыслим в категориях "вызов метода со статически выведенной сигнатурой", у нас сложность — какие у этого "дефолтового метода" будут параметры?

Какой-нибудь JS отвечает на это как раз тем способом, что и смолток: "любые". И вообще, у нас у любого метода любые параметры

Pzz>И, очевидное обобщение, относиться к набору конкретных методов как к такому pattern-matching с возможностью добавить pattern, который матчит всё, если не нашлось варианта получше...

Тут возникает важный вопрос — кто и когда выполняет этот паттерн-матчинг.
1. Статически, компилятор
2. Динамически, вызываюшая сторона
3. Динамически, вызываемая сторона


Pzz>Там любой тип может иметь методы.

В шарпе это называется extension methods, в D, емнип, uniform call syntax.
В нашем местном языке это называется dot-call syntax — любую функцию, которую можно вызвать как f(a, b), можно вызвать и как a.f(b). А присваивания вида a = a.f(b) эквивалентны a.=f(b).

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


Pzz>Тут напрашивается сравнение с LISP. Он ведь тоже такой, все запчасти нараспашку. Код документированным (и довольно внятным) образом является данными, хочешь — исполняй, хочешь во что-то другое перерабатывай.

И неспроста. Кей вдохновлялся именно LISP-ом, он об этом открыто пишет. А "объектность" они подсматривали в исходниках Симулы (про которую они почти ничего не знали, потому что вся документация и комментарии к коду были на немецком, которого никто из команды не знал).
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[5]: Недоучки по настоящему ООП не освоили (из-за Basic и С++)
От: Pzz Россия https://github.com/alexpevzner
Дата: 03.09.25 10:46
Оценка:
Здравствуйте, Sinclair, Вы писали:

S>Тем более, что пока мы мыслим в категориях "вызов метода со статически выведенной сигнатурой", у нас сложность — какие у этого "дефолтового метода" будут параметры?


Я думаю, что любые. Переданные в виде последовательности (массива) любых параметров.

Это как-то логично.

S>Какой-нибудь JS отвечает на это как раз тем способом, что и смолток: "любые". И вообще, у нас у любого метода любые параметры


У него, к сожалению, и у конкретных методов любые параметры.

Pzz>>И, очевидное обобщение, относиться к набору конкретных методов как к такому pattern-matching с возможностью добавить pattern, который матчит всё, если не нашлось варианта получше...

S>Тут возникает важный вопрос — кто и когда выполняет этот паттерн-матчинг.
S>1. Статически, компилятор
S>2. Динамически, вызываюшая сторона
S>3. Динамически, вызываемая сторона

Эээ. А если это встроенно в язык, в чём разница межды 2 и 3?
Re[6]: Недоучки по настоящему ООП не освоили (из-за Basic и С++)
От: Sinclair Россия https://github.com/evilguest/
Дата: 03.09.25 10:53
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Эээ. А если это встроенно в язык, в чём разница межды 2 и 3?

Примерно во всём. Например, вызывающая сторона проводит анализ того, что ей видно в точке вызова, принимает решение, и, возможно, кэширует результат байндинга для последующих вызовов.
Или, наоборот, вызываемая сторона при всяком повторном вызове в том же call site выполняет новый лукап того, что видно ей. И, например, делегирует вызов коду, которого в прошлый раз вообще в природе не было.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[2]: Недоучки по настоящему ООП не освоили (из-за Basic и С++)
От: novitk США  
Дата: 03.09.25 13:18
Оценка:
Здравствуйте, so5team, Вы писали:

S>>И автор говорит что настоящий ООП — был только в Smalltalk.

Спор схоластический. В моей практике под "настоящностью" Smalltalk обычно понимается, что есть только один тип вызова (call) в котором всегда есть первый параметер (receiver) со специальной семантикой.
В большинстве других языков парадигма вызова гибридная — статические функции, конструкторы, type classes, multiple dispatch и т.д.

S>Что до желания обсудить настоящесть ООП, предлагаю рассмотреть реализацию такого примера (псевдокод в синтаксисе a la C++, но на C++ это не реализуется):

Сколько будет у франкенштейна, полученого скрешением кошки с собакой, лап?
Re[7]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 15.09.25 05:43
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Теоретически, можно это сравнить с виртуальными классами C++. Но в Go конкретные типы, реализующие интерфейсы, не наследуют от этих интерфейсов, а просто реализуют их. Поэтому не возникает зависимости, нет необходимости как-то импортировать определение "базового класса" и т.п. Нет вот этого, как в C++, что даже если два разных определения одного и того же интерфейса в точности совпадают, то это всё равно два разных типа, и поди скрести их в одном наследнике.


В плюсах всё тоже самое делается на шаблонах
Маньяк Робокряк колесит по городу
Re[5]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 15.09.25 06:19
Оценка:
Здравствуйте, Shmj, Вы писали:

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


В недоучках — вся сила


S>Сам стараюсь таким быть.


А вот это очень заметно
Маньяк Робокряк колесит по городу
Re[8]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.09.25 14:00
Оценка:
Здравствуйте, Marty, Вы писали:

Pzz>>Теоретически, можно это сравнить с виртуальными классами C++. Но в Go конкретные типы, реализующие интерфейсы, не наследуют от этих интерфейсов, а просто реализуют их. Поэтому не возникает зависимости, нет необходимости как-то импортировать определение "базового класса" и т.п. Нет вот этого, как в C++, что даже если два разных определения одного и того же интерфейса в точности совпадают, то это всё равно два разных типа, и поди скрести их в одном наследнике.


M>В плюсах всё тоже самое делается на шаблонах


Насколько я понимаю, в C++ это примерно делается с помощью constraint-ов.

Ну и такой еще момент, гошная функция, которая понимает интерфейс, а не конкретный тип, будет сгенерирована в единственном экземпляре, а для конкретного типа, реализующего интерфейс, будет сгенерирован адаптер (VTAB). А C++-ный компилятор на темплейтах нашпандорит по экземпляру функции для каждого конкретного типа. Что может быть в одних случаях хорошо а в других не очень.
Re[9]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 15.09.25 19:06
Оценка:
Здравствуйте, Pzz, Вы писали:

M>>В плюсах всё тоже самое делается на шаблонах


Pzz>Насколько я понимаю, в C++ это примерно делается с помощью constraint-ов.


Это делается на шаблонах, просто если твой реальный тип, который ты подставил вместо шаблонного, что-то нужное не поддерживает, то скорее всего будет выдана длинная портянка сообщения. constraint-ы просто позволяют явно проверить условия на входе и генерируют более вменяемые сообщения об ошибках. И только.


Pzz>Ну и такой еще момент, гошная функция, которая понимает интерфейс, а не конкретный тип, будет сгенерирована в единственном экземпляре, а для конкретного типа, реализующего интерфейс, будет сгенерирован адаптер (VTAB). А C++-ный компилятор на темплейтах нашпандорит по экземпляру функции для каждого конкретного типа. Что может быть в одних случаях хорошо а в других не очень.


Т.е. там вся магия в рантайме, получается? В плюсах не так, всё в компайле, за счёт чего всё весьма шустро работает в итоге, и, кстати, не так уж и много места занимает. Хотя сейчас место вообще не проблема, но я на плюсах давно уже пишу прошивки к девайсам с весьма ограниченным количеством памяти, и особых проблем раздувания кода не видел
Маньяк Робокряк колесит по городу
Re[10]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.09.25 19:28
Оценка:
Здравствуйте, Marty, Вы писали:

M>Т.е. там вся магия в рантайме, получается? В плюсах не так, всё в компайле, за счёт чего всё весьма шустро работает в итоге, и, кстати, не так уж и много места занимает. Хотя сейчас место вообще не проблема, но я на плюсах давно уже пишу прошивки к девайсам с весьма ограниченным количеством памяти, и особых проблем раздувания кода не видел


В Go всё не так быстро, как в плюсах, но тоже довольно быстро.

Место не совсем не проблема. Много кода выносит кеш инструкций, а он не такой уж и большой.
Re[11]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: Marty Пират https://www.youtube.com/channel/UChp5PpQ6T4-93HbNF-8vSYg
Дата: 15.09.25 19:43
Оценка:
Здравствуйте, Pzz, Вы писали:

Pzz>Место не совсем не проблема. Много кода выносит кеш инструкций, а он не такой уж и большой.


Только по факту очень многое просто инлайнится, и преобразуется буквально в несколько инструкций, вместо того, чтобы делать несколько call'ов. Слухи о раздувании кода в плюсах несколько преувеличены.
Маньяк Робокряк колесит по городу
Re[12]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: Pzz Россия https://github.com/alexpevzner
Дата: 15.09.25 20:09
Оценка:
Здравствуйте, Marty, Вы писали:

Pzz>>Место не совсем не проблема. Много кода выносит кеш инструкций, а он не такой уж и большой.


M>Только по факту очень многое просто инлайнится, и преобразуется буквально в несколько инструкций, вместо того, чтобы делать несколько call'ов. Слухи о раздувании кода в плюсах несколько преувеличены.


Ну, много исходного кода — много машинного кода.

Go тоже умеет инлайнить. И в отличии от плюсов, он умеет инлаинить вызов функции из другого файла и даже из другого модуля. В обшем-то, гошному инлайнеру это всё равно.
Re[10]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: so5team https://stiffstream.com
Дата: 16.09.25 04:12
Оценка:
Здравствуйте, Marty, Вы писали:

Pzz>>Ну и такой еще момент, гошная функция, которая понимает интерфейс, а не конкретный тип, будет сгенерирована в единственном экземпляре, а для конкретного типа, реализующего интерфейс, будет сгенерирован адаптер (VTAB). А C++-ный компилятор на темплейтах нашпандорит по экземпляру функции для каждого конкретного типа. Что может быть в одних случаях хорошо а в других не очень.


M>Т.е. там вся магия в рантайме, получается? В плюсах не так


Умельцы уже сделали так, что и в C++ можно в рантайме: https://github.com/microsoft/proxy
Дендро-фекальным методом, как обычно.
Re[5]: Недоучки по настоящему ООП не освоили (из-за Basic и
От: Sinclair Россия https://github.com/evilguest/
Дата: 11.10.25 16:48
Оценка:
Здравствуйте, korvin_, Вы писали:

_>Могло бы быть похоже, если бы так можно было сделать. В C++, Java, C# так сделать нельзя.

В C# можно, для dynamic объектов.
Уйдемте отсюда, Румата! У вас слишком богатые погреба.
Re[4]: Недоучки по настоящему ООП не освоили (из-за Basic и С++)
От: ononim  
Дата: 12.10.25 07:45
Оценка:
D>CreateFile — какое сообщение и кому отправляет? Где ловят ответ на это сообщение? WIN API — это не только GUI. А GUI — это обмен сообщениями везде — не только в WINAPI.
IRP ы отправляет драйверу, но это уже совсем другая история.
Как много веселых ребят, и все делают велосипед...
Re[3]: Недоучки по настоящему ООП не освоили (из-за Basic и С++)
От: Философ Ад http://vk.com/id10256428
Дата: 15.10.25 16:26
Оценка:
Здравствуйте, Qulac, Вы писали:

Q>P.S. Про метаклассы, это ООП — космос который на практике почти не нужен, но наличие их дает некоторую логическую завершенность.


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