Comments 72
"Объект всегда имеет свой инстанс (как это по русски будет?)" масло всегда масляное?
Не совсем ясно, что здесь подразумевается под "инстанс".
Не совсем ясно, что здесь подразумевается под "инстанс".
Тавтология с точки зрения «традиционного» ООП, да. Инстанс — объект всегда «материален», присутствует в рантайме, в прочих ооп языках инстанс появляется только в момент new.
Я написал слово «инстанс» что бы было проще понять людям не сталкивавшимся с прототипным ооп, но видимо только запутал (:
Я написал слово «инстанс» что бы было проще понять людям не сталкивавшимся с прототипным ооп, но видимо только запутал (:
Про то что "инстанс" это экземпляр класса, то есть объект, в Жаваподобных ООП языках, я знаю.
Я же интересовался что _здесь_ подразумевалось под "инстанс"ом объекта.
Я же интересовался что _здесь_ подразумевалось под "инстанс"ом объекта.
Тогда фразу:
"Объект всегда имеет свой инстанс (как это по русски будет?)"
надо менять, т.к. см. первый комментарий. :)
"Объект всегда имеет свой инстанс (как это по русски будет?)"
надо менять, т.к. см. первый комментарий. :)
Э-э-э... Прошу прощения за оффтопик, но авторы того учебника сильно обманули во фразе "объект - это класс". "Класс - это объект" - тут да, всё правильно, а вот обратное в корне неверно.
" добавив/убрав из него нужны слоты"
это вы специально сократили слово нужные?
это вы специально сократили слово нужные?
Инстанс - сущность, экземпляр.
Спасибо за статью, будем расширять кругозор.
Спасибо за статью, будем расширять кругозор.
В принципе забавно, но интересно узнать практическое применение, где удобно выгодно, быстрее. Как и почему)
Практическое применение довольно обширно, в общем-то «common purpose» язык, выгодно везде где есть желание/необходимость делать сложные замороченные мегаизвраты метапрограммированием без потери структурности кода, написание кодогенераторов, DSL, парсеров, etc. Быстрее за счет нативной конкурентности на уровне потоков.
продолжайте, очень интересно
Заинтересовал язык...
Как кто-то здесь уже сказал: найти бы время поиграться с ним!
Как кто-то здесь уже сказал: найти бы время поиграться с ним!
Ээ а как синхронные сообщения "позволяют ввести прозрачную параллельность в язык без костылей".
Пара вопросов.
1)"объекты общались друг с другом не посредством вызова методов, а посредством передачи друг другу сообщений"
Чем посылка сообщений отличается от вызова метода?
2)"этот самый модуль ломится искать файл с именем класса."
Что делать с классами с одинаковыми названиями?
1)"объекты общались друг с другом не посредством вызова методов, а посредством передачи друг другу сообщений"
Чем посылка сообщений отличается от вызова метода?
2)"этот самый модуль ломится искать файл с именем класса."
Что делать с классами с одинаковыми названиями?
1. В общих чертах, внешне --- ничем. Внутреннее это другой подход (по-моему интуитивно понятно в чем разница) Если интересно почитайте статью про Smalltalk в википедии, там, вроде бы неплохо описано.
2. Классов с одинаковыми названиями в рамках одной сессии работы интерпретатора не бывает. (Я кстати опечатался, классов вообще не бывает, бывают только объекты)
2. Классов с одинаковыми названиями в рамках одной сессии работы интерпретатора не бывает. (Я кстати опечатался, классов вообще не бывает, бывают только объекты)
Про методы/сообщения - http://habrahabr.ru/blog/crazydev/45332.…
Если это действительно все различие то непонятно как это влияет на прозрачность параллельности, да и автору было бы неплохо привести пример реализации отличительной фичи.
Что, действительно непонятно? А если reciever object у меня на другой ноде? А если он динамически изменяется? Все еще непонятно?
Сообщение посылается удаленному объекту, а метод вызывается. Система сообщений по своей природе распределенная, сообщения проще сделать асинхронными и организовать поверх них модель актеров. Посмотрите вот эту презентацию Стива Декорте, что бы понять о чем я: http://iolanguage.com/docs/talks/2006-10…
Сообщение посылается удаленному объекту, а метод вызывается. Система сообщений по своей природе распределенная, сообщения проще сделать асинхронными и организовать поверх них модель актеров. Посмотрите вот эту презентацию Стива Декорте, что бы понять о чем я: http://iolanguage.com/docs/talks/2006-10…
По поводу вопроса №1.
В смысле вызова - ничем, а в смысле обработки - принципиально. В случае с отправкой сообщения - ни отправляющая, ни принимающая стороны не имеют информации друг о друге - в отличие от класс-ориентированного подхода, где интерфейсы объектов жёстко определяются интерфейсом класса.
Обрабатывать сообщение или отклонить - решает принимающая сторона. Говоря в терминах класс-ориентированного ООП, принимающая сторона имеет динамический интерфейс.
Такой подход понижает связность системы, а значит - делает её более устойчивой к изменениям, нежели чем при использовании статически типизированных классов. Во всяком случае, такую цель ставила себе команда XEROX Parc при реализации сообщений в Smalltalk.
На тему сообщений есть интересная статья (точное название не помню, из журнала "Byte" за 1981 год, найти можно на Smalltalk.ru). В ней описаны цели создания Smalltalk, как системы, основанной на сообщениях и преимущества такого подхода.
Асинхронность же тут ни при чём. И синхронная и асинхронная обработка сообщений примерно одинаково реализуются и в случае с вызовами, и в случае с сообщениями. По этим же причинам, мало общего с циклом сообщений Win32 API.
В смысле вызова - ничем, а в смысле обработки - принципиально. В случае с отправкой сообщения - ни отправляющая, ни принимающая стороны не имеют информации друг о друге - в отличие от класс-ориентированного подхода, где интерфейсы объектов жёстко определяются интерфейсом класса.
Обрабатывать сообщение или отклонить - решает принимающая сторона. Говоря в терминах класс-ориентированного ООП, принимающая сторона имеет динамический интерфейс.
Такой подход понижает связность системы, а значит - делает её более устойчивой к изменениям, нежели чем при использовании статически типизированных классов. Во всяком случае, такую цель ставила себе команда XEROX Parc при реализации сообщений в Smalltalk.
На тему сообщений есть интересная статья (точное название не помню, из журнала "Byte" за 1981 год, найти можно на Smalltalk.ru). В ней описаны цели создания Smalltalk, как системы, основанной на сообщениях и преимущества такого подхода.
Асинхронность же тут ни при чём. И синхронная и асинхронная обработка сообщений примерно одинаково реализуются и в случае с вызовами, и в случае с сообщениями. По этим же причинам, мало общего с циклом сообщений Win32 API.
Мне вот интересно, зачем называть привычные всем вещи другими названиями? Чтобы выделиться? Во многих языках есть глобальный объект/класс System или Runtime, зачем именовать его Lobby? Это нифига не интуитивно
Никакой принципиальной разницы между вызовом методов и отправкой сообщений нет. И то, и другое суть _вызов_ некоторого кода, разница лишь в _оформлении_ оного вызова. Физическая же реализация может быть какой угодно.
Саму идею отправки сообщений многие проходили еще при изучении win32 API функция SendMessage отправляла сообщение синхронно, а PostMessage асинхронно. Ничего положительного, кроме лишнего геморроя, такая система не давала, но зато позволяла писать на необъектно-ориентированных языках типа C. В нормальных же языках приходилось создавать обертки над этой системой (VCL).
Что же касается "классических" ОО-языков, типа C++, Object Pascal или Java, то нет никаких причин, кроме нежелания их разработчиков, реализовать асинхронный вызов методов. Метод, который следует вызывать асинхронно, можно отмечать модификатором при декларировании, например так:
class TMyClass
async procedure DoSmth(Param: Integer {любые другие параметры});
end;
При вызове такого метода происходит помещение параметров в очередь и немедленный возврат. Дальше код метода занимается обработкой переданных в очередь параметров либо последовательно, либо параллельно (в отдельных потоках), либо последовательно-параллельно через пул потоков. Сам по себе оный объект может находиться где угодно.
Таким образом, есть все основания полагать, что изыскания в области принципиальной разницы между вызовом методов и отправкой сообщений есть ни что иное, как создание "научной новизны" в области Computer Science какого-либо PhD student или еще кого.
Саму идею отправки сообщений многие проходили еще при изучении 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", а вовсе не наоборот ;-)
Тем более, тут еще встает вопрос о том, какой именно конструкцией реализовывать отправку сообщений. Если в стиле 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) и делает запрос к базе. Такая вот особая динамическая магия.
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, то в случае, когда нужен асинхронный вызов метода (я по прежнему настаиваю на том, что нет принципиальной разницы между методами и сообщениями), реализовать это несложно даже без нативной поддержки. Просто код разбивается на две части внешняя часть помещает параметры в очередь, внутренняя их разгребает.
Что же касается Object Pascal, то в случае, когда нужен асинхронный вызов метода (я по прежнему настаиваю на том, что нет принципиальной разницы между методами и сообщениями), реализовать это несложно даже без нативной поддержки. Просто код разбивается на две части внешняя часть помещает параметры в очередь, внутренняя их разгребает.
Если бы каждый автор не добавлял своих "особенных извратов", у Вас бы сейчас не было столь любимых стрелочек и точечек. Посмотрите на Smalltalk-80, такой синтаксис у первого оо-языка. Вообще, "прогресс не возможен без отклонений от нормы (с)", поэтому чем разнообразнее языки идейно и синтаксически, тем больше вероятность найти для себя подходящий инструмент :)
Принципиальная разница в использовании позднего связывания. "Сообщения" это просто вызов метода, да, но обязательно поиск обработчика должен происходить в рантайме.
в пхп есть волшебная функция __call которая вызывается, в случае отсутствия у объекта нужного метода.
Что касается реализации асинхронных методов в С++ и Object Pascal, то мне кажется, это вызвало бы больше вопросов, чем каких-то удобств. Поддержки многопоточности на уровне языка в этих языках нет, а асинхронный вызов подразумевает либо использование дополнительных потоков, либо передачу управления из основного потока в какие-то моменты времени в эти "помещённые в очередь вызовов" функции.
Что это за потоки, какие это будут моменты времени, как всем этим управлять непонятно.
А самое главное если смотреть шире, то сообщения между объектами, это всего лишь частный случай паттерна проектирования event dispatcher/subscriber. Не очень понятно, чем этот паттерн лучше всех остальных, чтобы его реализовывать на уровне конструкций языка, когда его можно реализовать имеющимися средствами, имея в результате бОльший контроль над получившейся системой.
Что это за потоки, какие это будут моменты времени, как всем этим управлять непонятно.
А самое главное если смотреть шире, то сообщения между объектами, это всего лишь частный случай паттерна проектирования event dispatcher/subscriber. Не очень понятно, чем этот паттерн лучше всех остальных, чтобы его реализовывать на уровне конструкций языка, когда его можно реализовать имеющимися средствами, имея в результате бОльший контроль над получившейся системой.
Мне кажется, что рекурсивное вычисление факториала - не самый лучший способ.
Вам шашечки или ехать? Это сэмпл, самый простой который пришел мне в голову, когда я писал. Не слишком перегруженный, не слишком сложный.
Кстати, по теме:
Number ! := method(self * (self - 1)!)
0 ! := 1
Io> 5!
==> 120
(ахтунг тут: http://pastie.org/225449)
Number ! := method(self * (self - 1)!)
0 ! := 1
Io> 5!
==> 120
(ахтунг тут: http://pastie.org/225449)
прототипное ооп - то ещё недоразумение. оно ещё годится к применению в смалтолке, потому как разработка для него происходит исключительно интерактивно в среде разработки. для более традиционных способов написания программ, состоящих и двух последовательных этапов: написание и интерпретация, - прототипное ооп не годится совершенно. всё-равно выделяются объекты, выполняющие функции классов (хранение общих для всех экземпляров свойств в одном месте). либо не выделяются и получается каша-малаша.
опять же старая добрая проблема пространств имён. есть два модуля, каждый из них создаёт, объект Lobby.RSS, только один из них реализует rss1, а другой - rss2. а мы хотим иметь возможность в нашем приложении создать оба рсс-а.
а вообще, автолоад - то ещё зло. если у нас есть два файла с одинаковым именем, но в разных директориях - начинается веселье с редактированием не того файла.
простота и элегантность программы типа "привет мир" - ничто по сравнению с необходимостью отлаживать последствия такой вот самодеятельности.
опять же старая добрая проблема пространств имён. есть два модуля, каждый из них создаёт, объект Lobby.RSS, только один из них реализует rss1, а другой - rss2. а мы хотим иметь возможность в нашем приложении создать оба рсс-а.
а вообще, автолоад - то ещё зло. если у нас есть два файла с одинаковым именем, но в разных директориях - начинается веселье с редактированием не того файла.
простота и элегантность программы типа "привет мир" - ничто по сравнению с необходимостью отлаживать последствия такой вот самодеятельности.
Epic Fail. В Смолтоке небыло прототипного ооп.
Вы когда-нибудь что-либо крупное на lisp'е писали? Я вот писал, знаете, ничего удобнее REPL еще не придумали для отладки, можете погуглить историю, как люди дебажили lisp код находящийся в глубоком космосе. А пространства имен можно запортачить и в java, нужно просто понимать что ты делаешь, вот и все.
Вы когда-нибудь что-либо крупное на 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
а насчёт репла - смешно, да. из шэлла ковырять многовложенную функцию - занятие для настоящего любителя сэкса..
гугль, вот, со мной согласен: 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
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 :
http://www.mail-archive.com/debian-mentors@lists.debian.org/msg54241.html
Не за что, приходите, будет еще. А вот ставить io я бы рекомендовал из исходников. У меня eeeXubuntu собралось с полпинка.
Sign up to leave a comment.
Io Language: Объектная система