Обновить
101
0.1
Роман Смирнов@Source

Head of Elixir at Ecom.tech

Отправить сообщение

Да, содержимое сообщения — это просто данные. Но чтобы его отправить нужно ещё выбрать способ отправки и получателя. Итого, данные, отправляемые адресату выбранным способом, — это сообщение. Пока данные никому не отправляются — это не сообщение. Этого достаточно чтобы выделить отдельный концепт.


Наконец, я же могу на Erlang-е и без акторов обойтись?

В том то и вся прелесть, что не можете. Всё есть акторы и ничего вне акторов не существует.

Можно ссылочку на негодование Кэя по этому поводу?

Есть цитата по поводу почему отказались от полноценных сообщений:


Take a look at the first implemented Smalltalk (-72). It implemented objects internally as a "receive the message" mechanism — a kind of quick parser — and didn't have dedicated selectors. (You can find "The Early History of Smalltalk" via Google to see more.)
This made the first Smalltalk "automatically extensible" in the dimensions of form, meaning, and pragmatics.

When Xerox didn't come through with a replacement for the Alto we (and others at Parc) had to optimize for the next phases, and this led to the compromise of Smalltalk-76 (and the succeeding Smalltalks). Dan Ingalls chose the most common patterns that had proved useful and made a fixed syntax that still allowed some extension via keywords. This also eliminated an ambiguity problem, and the whole thing on the same machine was about 180 times faster.

В общем, в Smalltalk когда-то были полноценные сообщения:


In Smalltalk-72, a message send was just a "notify" to the receiver that there was a message, plus a reference to the whole message. The receiver did the actual work of looking at it, interpreting it, etc.

Но их выпилили из-за performance-проблем, а терминология осталась. Отсюда и вся путаница.

Да не обязательно. Никто не заставляет как-то обрабатывать этот ответ. Этим сообщения и отличаются от вызова метода. Получатель может их игнорировать.


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

Почти в той же мере, в какой в Erlang-овских сообщениях зашита информация о том, какое выражение будет использовано для его обработки, нет?

Нет. Я могу знать, что какое-то сообщение попадёт в handle_call или в handle_cast, но от сообщения это никак не зависит. Обработчик зависит от того каким способом отправлено сообщение, а не от его содержания.


А может быть, есть шанс получить акторы без Erlang-овских заморочек?

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


ограничиваясь «нормальными» объектами там в остальных случаях

Зачем нужны «нормальные» объекты? Если не нужен полноценный объект, ограничьтесь обычным значением или структурой.
Не знаю, как там Smalltalk обходит performance-проблемы от этой бесполезной упаковки простых данных в объекты. А бедные C#/Java/etc. с бесконечным boxing/unboxing только маются.

То есть встретить объект, состоящий из других объектов было бы тоже крайне странно. ;)

Угу, поэтому состояние объекта и не должно состоять из других объектов.


  1. Objects have their own memory, which consists of other objects.

Это формулировка Тима Бадда из книги "An Introduction to Object-Oriented Programming", которая со Smalltalk не особо связана.
А у Кея было так:


  1. Everything is an object.
  2. Objects communicate by sending and receiving messages (in terms of objects).
  3. Objects have their own memory (in terms of objects).

Причём он сам был недоволен, как Бадд переврал его определение, изменив смысл. Вот тут можно подробнее почитать, в том числе и про то, что версии Smalltalk до Smalltalk-80 базировались на модели акторов. В принципе, можно сказать, что Smalltalk-80 свернул на кривую дорожку и отказался от ООП в исходном понимании.


P.S. Собственно, чего тут спорить, Кей тут на днях сам написал, что
Erlang is much closer to the original ideas I had about “objects” and how to use them.
Можете с ним лично поспорить, если хотите :-)

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

Эх, я помню, как в 2005 году качал DRKB (Delphi Russian Knowledge Base) в CHM-формате, которую надо было ещё порезать на 3 части, чтобы на дискеты влезло. И это получилось провернуть только со второго раза. В первый раз отведённого часа в интернет-центре не хватило, чтобы скачать эти 3.5 Mb

Дело в том, что «Erlang-овский ООП» не предполагает никакого ООП на уровне «ниже процессов»

С одной стороны — да, с другой — это всё-таки не уровень ОС, это легковесные процессы виртуальной машины. И их может быть много тысяч на одной машине.


А по поводу внутреннего устройства, так это и к клеткам применимо. Даже если любой организм состоит из клеток, то внутри клетки очевидно не другие клетки, а митохондрии, рибосомы и т.д. Другими словами, встретить объект внутри объекта было бы крайне странно.
Поэтому я бы сказал, что пункт «все есть объект» в Erlang тоже выполняется, т.к. нет никакой возможности выполнить какой-то код вне актора. А пункта «объект должен состоять из других объектов» вроде никогда не было.

На следующем митапе можем обсудить )

В Smalltalk-е тоже прием сообщения и код реакции не связаны напрямую!

Вообще связаны, в штатном для Smalltalk случае, в самом "сообщении" зашита информация какой метод будет вызван для его обработки.


Да, если вы будете принимать все сообщения через doesNotUnderstand, потом их как-то асинхронно обрабатывать, и возвращать результат через thisContext — то есть шанс получить кривую и не очень стабильную реализацию Erlang поверх Smalltalk. Весь вопрос в том, что это будет неестественно для Smalltalk. Настоящие сообщения неестественны для Smalltalk, но да — теоретически их можно эмулировать, правда, для этого ещё придётся полностью переписать стандартную библиотеку.


сообщение не обязательно связывается с выполняемым кодом по имени метода

Вы "не" не туда поставили. Должно быть "обязательно не связывается".

экземпляр BackTalker-а получая сообщение talkBack, посылает сообщение отправителю — обмен сообщениями? Обмен!

Если вы будете все результаты вычислений пересылать через thisContext — это весьма быстро превратится в треш и угар. В Smalltalk это скорее хак для редкого применения, чем что-то чем можно пользоваться для ежедневного применения.
А так да, из любого Тьюринг-полного языка можно сделать плохой Erlang (эмуляцию обмена сообщениями и т.д.), с этим никто не спорит. Даже в статье про это было.


Нет обязательного обмена сообщениями — как и в Erlang-е, кстати ;)

Что так? В Erlang он вполне себе обязателен на уровне акторов, никакого другого пути кроме обмена сообщениями в нём просто нет.


Ага, и нет зайцев, как отдельного от животных понятия?

Ну, допустим, зайца, не являющегося животным, найти можно: плюшевого, нарисованного и т.п.


А в Erlang-е нет понятия сообщения как отдельного от понятия валидный терм (т.е. от понятия «данные»). Бардак!!! ;)

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

Здравому смыслу :-)
Нельзя сказать, что объекты обмениваются сообщениями, если сообщения — это тоже объекты. Получается, объекты обмениваются объектами, а точнее не обмениваются, потому что ответное сообщение невозможно отправить тому, кто прислал входящее. Короче, бардак: нет ни обмена сообщениями, ни самих сообщений, как отдельного от объектов понятия.

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

Если у вас не будет никакого другого способа вернуть значение, то да — многое поменяется.


сами сообщения в Smalltalk остаются при этом не менее настоящими, чем в Erlang? или же в первом что-то не так именно с самими сообщениями? что именно?

В конечном итоге, в Smalltalk всё равно есть соответствие "сообщение — метод", кроме спец.исключения doesNotUnderstand. В Erlang все сообщения обрабатываются через стандартные behaviours, типа этого. Таким образом, приём сообщений и код реакции не связаны напрямую. Например, вы можете переименовать функцию, которая реализует реакцию на сообщение, но вся остальная программа об этом не узнает, не надо будет менять код отправки этого сообщения. И даже роль почтальона играет отдельный модуль


gen_server:call(pid_or_pname, message)
Вы упорно отказываетесь различать объекты и акторы, а это, очевиднейшим образом, разные вещи, что прекрасно видно на приведенном вами примере.

Я не отказываюсь их различать. Я намеренно их объединяю в одно понятие в рамках данной дискуссии, поскольку объекты изначально задумывались как акторы:


I'm sorry that I long ago coined the term "objects" for this topic because it gets many people to focus on the lesser idea. The big idea is "messaging".
I thought of objects being like biological cells and/or individual computers on a network, only able to communicate with messages. © Alan Kay


Что тут важно? Биологическая клетка или компьютер в сети — это активная действующая единица. На самом деле, термин "объект" крайне неудачно подходит для самой концепции, поскольку имеется в виду субъект действия, который может общаться с другими субъектами посредством обмена сообщениями. Всё остальное вторично.


Именно так реализованы акторы в Erlang/OTP. А объекты в Smalltalk реализованы не так (хотели так, но видимо для 1969 года идея оказалась слишком сложной). Глупо думать о книге, о строке, или о числе, как об отдельном компьютере в сети (даже умозрительно это был бы абсолютно иррациональный оверхэд, вдобавок затрудняющий понимание функционирования сети), поэтому они не могут быть объектами в Кеевском понимании. Вот собственно и всё резюме.


Объекты (по умолчанию) ничего не делают сами по себе, они лишь реагируют на сообщения

Сообщение можно интерпретировать как приказ/задачу сделать что-либо. Дальше объект должен мочь что-то сделать сам по себе (отреагировать). Книга, как объект физической реальности, не способна никак отреагировать, хоть сколько ей ни приказывай. Вам придётся самому что-то с ней сделать, чтобы она как-то изменилась, не путём сообщений, а путём прямого физического воздействия.


Книга не может менять название? Расскажите об этом писателям.

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


P.S. Не воспринимайте всё так, как-будто я не знаком с ООП во всех его современных проявлениях. Я специально пишу в такой манере, чтобы Вы могли взглянуть на вещи под другим углом, скинув привычные шоры.

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

После этой фразы я ожидал поворот статьи в сторону Haskell, или хотя бы PureScript :-)

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


Проблема популярного ООП, в том числе и в Smalltalk, что создатели ЯП решили всё подряд назвать объектами (всё-таки неудачный термин, актор — гораздо точнее соответствует идеям Кея). И ещё внедрить напрочь безумную идею, что это похоже на реальный мир. Я вот ни разу не видел книгу, которая могла бы сама себе поменять название или посчитать кол-во страниц в себе. Потому что книга — это просто структура данных (да ещё и иммутабельная, если её не портить), и никаких методов она иметь не может. А в ООП-программах подобная дичь сплошь и рядом.

Да, в этом заключается идея синхронной посылки сообщения.

Вовсе необязательно. Можно ждать ответного сообщения.


В случае Smalltalk надо бы еще уточнить, что такое «вся программа».

Ну ok, в Smalltalk сама среда вряд ли упадёт, но остаться в состоянии, неспособном обрабатывать последующие запросы, вполне может.


В моем текущем (и не только моем) понимании сообщение отличается от вызова функции

Я думаю, непонимание цитаты началось именно с придирки к слову "функция", там очевидно имелся в виду "вызов метода". И про late binding (который Вы описали и который есть в куче ЯП) все знают, но это всё равно не обмен сообщениями. В Smalltalk у вызывающего объекта нет никакого способа получить ответ в виде сообщения. Как следствие, ни о каком обмене сообщениями говорить не приходится.

Вот это «по сути» — можно раскрыть? Где коренится эта самая суть?

В этой ветке уже многократно описали чем отличается пересылка сообщений в Erlang от вызова метода в какой-нибудь Java. А в чём тут отличие между Java и Smalltalk?
И там и там, получатель обязан иметь строго заданный тип (быть экземпляром класса, реализующего определённый интерфейс/протокол). И там и там, вызывающий объект не принимает сообщения от другого объекта, а ждёт return вызванного метода. И там и там объекты не изолированы на уровне виртуальной машины, как следствие вызов метода может уронить вызывающий объект, а точнее говоря всю программу.


Разве в Erlang сообщение — не «просто» терм? …А в Smalltalk — «просто» объект (но никак не метод) ;)

"«просто» объект"? В этом вся и проблема, в Smalltalk нет фактического разделения на объекты и сообщения. Есть только болтовня на эту тему.
Представьте, что объекты — это люди, которые выполняют какую-то работу. У каждого человека есть свои должностные обязанности. И ему прилетают задачи (сообщения) и встают в очередь того, что надо сделать. Человек постепенно делает эти задачи. Если не знает как сделать, то отправляет другому человеку, ну или в мусорку, в зависимости от должностных инструкций.
Собственно, Кей именно про такое и говорил, только на примере клеток. И что предлагает Smalltalk? Пересылать людей друг другу вместо обмена сообщениями :facepalm:

Как это?!? Если говорить о Smalltalk как о языке, то сообщения лежат в основе его синтаксиса — разве это не та самая «концепция»?

Разве "сообщение" в Smalltalk — это не объект? А оно обязано быть не объектом, чтобы быть чем-то иным по факту, а не на словах.

Я думаю, имелось в виду, что реализация обработки "сообщений" в Smalltalk ничем по сути не отличается от вызова метода в языках типа C++, Java и т.д. А в Erlang/Elixir она принципиально иначе реализована. Сообщение тут это не объект и не метод, а именно сообщение и ничто больше. Отправить его можно при желании кому угодно (любому актору), как и почтовый конверт любому адресату.

Информация

В рейтинге
3 216-й
Откуда
Россия
Работает в
Зарегистрирован
Активность