Как стать автором
Обновить

Комментарии 72

"Объект всегда имеет свой инстанс (как это по русски будет?)" — масло всегда масляное?
Не совсем ясно, что здесь подразумевается под "инстанс".
Тавтология с точки зрения «традиционного» ООП, да. Инстанс — объект всегда «материален», присутствует в рантайме, в прочих ооп языках инстанс появляется только в момент new.
Я написал слово «инстанс» что бы было проще понять людям не сталкивавшимся с прототипным ооп, но видимо только запутал (:
Тот же жаваскрипт — язык с прототипным ООП, так что, я думаю, многие сталкивались. :)
Проще говоря - объект есть, его не может не быть.
НЛО прилетело и опубликовало эту надпись здесь
Про то что "инстанс" — это экземпляр класса, то есть объект, в Жаваподобных ООП языках, я знаю.
Я же интересовался — что _здесь_ подразумевалось под "инстанс"ом объекта.
НЛО прилетело и опубликовало эту надпись здесь
Тогда фразу:
"Объект всегда имеет свой инстанс (как это по русски будет?)"
надо менять, т.к. см. первый комментарий. :)
НЛО прилетело и опубликовало эту надпись здесь
Э-э-э... Прошу прощения за оффтопик, но авторы того учебника сильно обманули во фразе "объект - это класс". "Класс - это объект" - тут да, всё правильно, а вот обратное в корне неверно.
Применительно к руби верно и обратное. Обявление класса в руби так же является объектом.
Ещё раз: фраза "класс - это объект" верна (для Ruby), фраза "объект - это класс" ошибочна.

ontopic: А вот для прототипных языков, кстати, фразу "объект - это класс" в некотором приближении можно считать верной.
Неправильно вас понял :)
может, они имели в виду, что Object тоже класс? ;)
" добавив/убрав из него нужны слоты"
это вы специально сократили слово нужные?
Опечатался, спасибо, поправлю.
Инстанс - сущность, экземпляр.
Спасибо за статью, будем расширять кругозор.
В принципе забавно, но интересно узнать практическое применение, где удобно выгодно, быстрее. Как и почему)
Практическое применение довольно обширно, в общем-то «common purpose» язык, выгодно везде где есть желание/необходимость делать сложные замороченные мегаизвраты метапрограммированием без потери структурности кода, написание кодогенераторов, DSL, парсеров, etc. Быстрее за счет нативной конкурентности на уровне потоков.
Термин "замороченные мегоизвраты" мне уже нравится)
Найти бы свободное время что бы поиграться, эх. Сам код мне нравится.
продолжайте, очень интересно
Спасибо, еще минимум две статьи будет.
даешь пять! ;)
Заинтересовал язык...
Как кто-то здесь уже сказал: найти бы время поиграться с ним!
Ээ а как синхронные сообщения "позволяют ввести прозрачную параллельность в язык без костылей".
Кто сказал синхронные? (:
Вообще сделать асинхронными сообщения по-моему проще, чем вызов методов.
Пара вопросов.
1)"объекты общались друг с другом не посредством вызова методов, а посредством передачи друг другу сообщений"

Чем посылка сообщений отличается от вызова метода?

2)"этот самый модуль ломится искать файл с именем класса."

Что делать с классами с одинаковыми названиями?
1. В общих чертах, внешне --- ничем. Внутреннее это другой подход (по-моему интуитивно понятно в чем разница) Если интересно почитайте статью про Smalltalk в википедии, там, вроде бы неплохо описано.
2. Классов с одинаковыми названиями в рамках одной сессии работы интерпретатора не бывает. (Я кстати опечатался, классов вообще не бывает, бывают только объекты)
Если это действительно все различие то непонятно как это влияет на прозрачность параллельности, да и автору было бы неплохо привести пример реализации отличительной фичи.
Что, действительно непонятно? А если reciever object у меня на другой ноде? А если он динамически изменяется? Все еще непонятно?
Сообщение посылается удаленному объекту, а метод вызывается. Система сообщений по своей природе распределенная, сообщения проще сделать асинхронными и организовать поверх них модель актеров. Посмотрите вот эту презентацию Стива Декорте, что бы понять о чем я: http://iolanguage.com/docs/talks/2006-10…
По поводу вопроса №1.

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

Обрабатывать сообщение или отклонить - решает принимающая сторона. Говоря в терминах класс-ориентированного ООП, принимающая сторона имеет динамический интерфейс.

Такой подход понижает связность системы, а значит - делает её более устойчивой к изменениям, нежели чем при использовании статически типизированных классов. Во всяком случае, такую цель ставила себе команда XEROX Parc при реализации сообщений в Smalltalk.

На тему сообщений есть интересная статья (точное название не помню, из журнала "Byte" за 1981 год, найти можно на Smalltalk.ru). В ней описаны цели создания Smalltalk, как системы, основанной на сообщениях и преимущества такого подхода.

Асинхронность же тут ни при чём. И синхронная и асинхронная обработка сообщений примерно одинаково реализуются и в случае с вызовами, и в случае с сообщениями. По этим же причинам, мало общего с циклом сообщений Win32 API.
Мне вот интересно, зачем называть привычные всем вещи другими названиями? Чтобы выделиться? Во многих языках есть глобальный объект/класс System или Runtime, зачем именовать его Lobby? Это нифига не интуитивно
Ну вот сколько я пишу на io мне еще ни разу не приходилось обращаться к Lobby по имени. Почему нет?
Никакой принципиальной разницы между вызовом методов и отправкой сообщений нет. И то, и другое — суть _вызов_ некоторого кода, разница лишь в _оформлении_ оного вызова. Физическая же реализация может быть какой угодно.

Саму идею отправки сообщений многие проходили еще при изучении win32 API — функция SendMessage отправляла сообщение синхронно, а PostMessage асинхронно. Ничего положительного, кроме лишнего геморроя, такая система не давала, но зато позволяла писать на необъектно-ориентированных языках типа C. В нормальных же языках приходилось создавать обертки над этой системой (VCL).

Что же касается "классических" ОО-языков, типа C++, Object Pascal или Java, то нет никаких причин, кроме нежелания их разработчиков, реализовать асинхронный вызов методов. Метод, который следует вызывать асинхронно, можно отмечать модификатором при декларировании, например так:

class TMyClass
async procedure DoSmth(Param: Integer {любые другие параметры});
end;

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

Таким образом, есть все основания полагать, что изыскания в области принципиальной разницы между вызовом методов и отправкой сообщений есть ни что иное, как создание "научной новизны" в области Computer Science какого-либо PhD student или еще кого.
Здраво, но по факту мы имеем кривую реализацию вызова и хотя бы отдаленно прямую реализацию посылки сообщений.
Сообщения, по-моему, более человекоподобны, все-таки.
Не вижу здесь никакой кривоты. Реализация аналогична реализации посылки синхронных/асинхронных сообщений, именно в силу отсутствия принципиальной разницы. Можно даже сказать, что методы — это своего рода красивая обертка для отправки сообщений :-)

Тем более, тут еще встает вопрос о том, какой именно конструкцией реализовывать отправку сообщений. Если в стиле win23 API — SendMessage(Instance, Message, WParam, LParam) — то ничего человечного тут нет. Куда более человечным будет Instance.Message(WParam, LParam).

Что же касается конструкций описываемого Вами языка, то ничем иным, кроме желания у его автора выпендриться, я не могу объяснить замену "." или на худой конец "->" пробелами. Ибо как Вы совершенно верно показали в своей предыдущей заметке по теме, никакой принципиальной разницы между Instance print и Instance.print не существует (в том числе и в плане человечности). И то, и другое — это вызов некоего кода, который делает что-то с объектом Instance. Как именно называть это — "вызов метода" или "отправка сообщения" — совершенно неважно, ибо ПО СУТИ действие одно — выполнение некоторого кода в контексте объекта Instance.

Если же говорить о человекоподобности, то человекоподобным будет print "Hello world", а вовсе не наоборот ;-)
Заменя . -> и прочего мусора на " " обусловлена двумя факторами: 1. Наследие Smalltalk'а (А там именно так) 2. Стремление максимально упростить синтаксис.
А в остальном я с вами даже соглашусь, хотя вы сами пишете о том, что вызов метода --- обертка над асинхронным сообщением, тут мы минуя обертку получаем что хотим и все дела (:
Это ТОЖЕ обертка, просто оформленная иначе и ничего более :-)
Разница есть. Если в "классическом" ооп-языке у объекта вызывается несуществующий метод, то код либо не собирается, либо падает в рантайме. А если язык отсылает именно сообщение, то у объекта-получателя есть возможность это сообщение обработать (независимо от того, есть у него соответствующий метод или нет). Например, таким образом можно сделать элегантную реализацию прокси (все сообщения, пришедшие объекту Б, отправляем объекту С). Или вот такой syntax sugar (ruby):

User.find_by_title_and_author_id("First post", @author);

Тут класс User получает сообщение "find_by_title_and_author_id", парсит его, выдирает поля для поиска (title и author_id) и делает запрос к базе. Такая вот особая динамическая магия.
Ничто не мешает добавить линковку несуществующего метода на некий универсальный вида DispatchUnknownMethod(const Name: String; const Params: array of const);
Было бы желание у разработчика компилятора.

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

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

Что же касается Object Pascal, то в случае, когда нужен асинхронный вызов метода (я по прежнему настаиваю на том, что нет принципиальной разницы между методами и сообщениями), реализовать это несложно даже без нативной поддержки. Просто код разбивается на две части — внешняя часть помещает параметры в очередь, внутренняя их разгребает.
Если бы каждый автор не добавлял своих "особенных извратов", у Вас бы сейчас не было столь любимых стрелочек и точечек. Посмотрите на Smalltalk-80, такой синтаксис у первого оо-языка. Вообще, "прогресс не возможен без отклонений от нормы (с)", поэтому чем разнообразнее языки идейно и синтаксически, тем больше вероятность найти для себя подходящий инструмент :)
Насчет стрелочек не соглашусь. Мне нравится pascal-style синтаксис.

Что же касается разнообразия, то достало после php писать в delphi что-то вида for(), а после delphi в php писать for i := 0 to :-)))
Принципиальная разница в использовании позднего связывания. "Сообщения" — это просто вызов метода, да, но обязательно поиск обработчика должен происходить в рантайме.
Для позднего связывания есть dispinterface :-)
в пхп есть волшебная функция __call которая вызывается, в случае отсутствия у объекта нужного метода.
В пхп много чего есть, только этим мало кто пользуется.
в пхп много чего есть только почти все через жопу
не без этого
пхп-пхп, а в Perl есть AUTOLOAD!
Что касается реализации асинхронных методов в С++ и Object Pascal, то мне кажется, это вызвало бы больше вопросов, чем каких-то удобств. Поддержки многопоточности на уровне языка в этих языках нет, а асинхронный вызов подразумевает либо использование дополнительных потоков, либо передачу управления из основного потока в какие-то моменты времени в эти "помещённые в очередь вызовов" функции.

Что это за потоки, какие это будут моменты времени, как всем этим управлять — непонятно.

А самое главное — если смотреть шире, то сообщения между объектами, это всего лишь частный случай паттерна проектирования event dispatcher/subscriber. Не очень понятно, чем этот паттерн лучше всех остальных, чтобы его реализовывать на уровне конструкций языка, когда его можно реализовать имеющимися средствами, имея в результате бОльший контроль над получившейся системой.
Согласен с Вашим высказыванием. Лично я отлично обхожусь без асинхронных вызовов методов в Object Pascal, ибо способов их реализовать есть несколько. Мое возражение касалось исключительно высказываний о принципиальной разнице (и преимуществе) т.н. концепции "сообщений" над методами.
Мне кажется, что рекурсивное вычисление факториала - не самый лучший способ.
Вам шашечки или ехать? Это сэмпл, самый простой который пришел мне в голову, когда я писал. Не слишком перегруженный, не слишком сложный.
Кстати, по теме:

Number ! := method(self * (self - 1)!)
0 ! := 1

Io> 5!
==> 120

(ахтунг тут: http://pastie.org/225449)
прототипное ооп - то ещё недоразумение. оно ещё годится к применению в смалтолке, потому как разработка для него происходит исключительно интерактивно в среде разработки. для более традиционных способов написания программ, состоящих и двух последовательных этапов: написание и интерпретация, - прототипное ооп не годится совершенно. всё-равно выделяются объекты, выполняющие функции классов (хранение общих для всех экземпляров свойств в одном месте). либо не выделяются и получается каша-малаша.

опять же старая добрая проблема пространств имён. есть два модуля, каждый из них создаёт, объект Lobby.RSS, только один из них реализует rss1, а другой - rss2. а мы хотим иметь возможность в нашем приложении создать оба рсс-а.
а вообще, автолоад - то ещё зло. если у нас есть два файла с одинаковым именем, но в разных директориях - начинается веселье с редактированием не того файла.
простота и элегантность программы типа "привет мир" - ничто по сравнению с необходимостью отлаживать последствия такой вот самодеятельности.
Epic Fail. В Смолтоке небыло прототипного ооп.
Вы когда-нибудь что-либо крупное на lisp'е писали? Я вот писал, знаете, ничего удобнее REPL еще не придумали для отладки, можете погуглить историю, как люди дебажили lisp код находящийся в глубоком космосе. А пространства имен можно запортачить и в java, нужно просто понимать что ты делаешь, вот и все.
боже упаси писать что-либо на лиспе, тем более крупное..
гугль, вот, со мной согласен: http://www.google.com/search?ie=UTF-8&oe=UTF-8&sourceid=navclient&gfns=1&q=%D0%B8%D1%81%D1%82%D0%BE%D1%80%D0%B8%D1%8E%2C+%D0%BA%D0%B0%D0%BA+%D0%BB%D1%8E%D0%B4%D0%B8+%D0%B4%D0%B5%D0%B1%D0%B0%D0%B6%D0%B8%D0%BB%D0%B8+lisp+%D0%BA%D0%BE%D0%B4+%D0%BD%D0%B0%D1%85%D0%BE%D0%B4%D1%8F%D1%89%D0%B8%D0%B9%D1%81%D1%8F+%D0%B2+%D0%B3%D0%BB%D1%83%D0%B1%D0%BE%D0%BA%D0%BE%D0%BC+%D0%BA%D0%BE%D1%81%D0%BC%D0%BE%D1%81%D0%B5

а насчёт репла - смешно, да. из шэлла ковырять многовложенную функцию - занятие для настоящего любителя сэкса..
Чот я потерял мысль. При чем тут шелл? Вы вообще лисп в глаза видели? А ide для лиспа?
которую иде? не емакс случаем =)
шелл - это не только баш, если что...
И даже более впечатляющий пример удаленной отладки произошел в миссии NASA «Deep Space 1» в 1998 году. Через полгода после запуска космического корабля, небольшой код на Lisp должен был управлять космическим кораблем в течении двух дней для проведения серии экспериментов. Однако, неуловимая race condition в коде не была выявлена при тестировании на земле и была обнаружена уже в космосе. Когда ошибка была выявлена в космосе (100 миллионов миль от Земли) команда смогла произвести диагностику и исправление работающего кода, что позволило завершить эксперимент.

(c) PCL (http://pcl.catap.ru/doku.php?id=pcl:%D1%…)
о, да, делать всё через задницу - это очень в духе лиспа =) вместо того, чтобы взять исходники/дамп_состояния, запустить на виртуальной машине и отдебажить, они предпочли трахаться с удалённой отладкой.
Вам-то виднее, ясен пень (:
какой-то гугол не постоянный...
http://img-fotki.yandex.ru/get/26/sairi-na-tenshi.6/0_1142d_4299be4f_orig
спасибо за отличные статьи - с удовольствием читаю.
решал себе поставить сабж, но не нашел его в репах дебиана :(

вот неофициальный репозитарий сборок IO :

http://www.mail-archive.com/debian-mentors@lists.debian.org/msg54241.html
Не за что, приходите, будет еще. А вот ставить io я бы рекомендовал из исходников. У меня eeeXubuntu собралось с полпинка.
А вот ставить io я бы рекомендовал из исходников.

в ссылке, что я дал, как раз указан deb-src репозитарий
т.е. ставится так:

apt-get -b source iolanguage
и потом dpkg -i iolanguage-bla-bla.deb
Ну обычно я качаю тарболл с официального сайта, или беру прямо из гита.
Так оно как-то спокойнее (:
Зарегистрируйтесь на Хабре , чтобы оставить комментарий

Публикации

Истории