Pull to refresh

Io Language: Объектная система

Abnormal programming *

Введение


Продолжая писать про io, совершенно необходимо остановиться отдельно на устройстве объектной системы этого чудесатого езычка. Главная проблема в том, что даже если вы «знаете» ООП, вполне может сложиться ситуация, что вы просто не поймете, как оно устроено в io. Сейчас под ООП почему-то подразумевается модель Java, чаще всего. C++ нельзя назвать объектно-ориентированным языком, потому что он язык поддерживающий парадигму ООП, но это не его основная парадигма. Java больше подходит под гордое звание Ъ-ООП языка, но вот беда, ООП диктуемое Java-like языками довольно извращено. Изначально принципы ООП зарождались в Smalltalk'е и там все выглядело несколько иначе, объекты общались друг с другом не посредством вызова методов, а посредством передачи друг другу сообщений, мне до сих пор странно, почему же от этой модели ушли, ведь такое построение позволяет ввести прозрачную параллельность в язык без костылей. Посмотрите на нынешние круто параллелящиеся языки, тот же Erlang например, там все сделано через сообщения. Опять же нагородили огородов из RPC, COM и прочего dbus'а. А ведь как все хорошо начиналось.


Прототипное ООП


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

Глянем на прототипы, в двух словах я описывал структуру в первой статье, но на всяких случай напомню. Прототипность языка заключается в том, что напрочь отсутствуют такие понятия как класс, экземпляр класса и прочее связанное с разделением декларации типа и данных, в io есть только объекты. Объект всегда имеет свой инстанс (как это по русски будет?), получить новый объект можно клонировав старый и изменив его свойства, добавив/убрав из него нужные слоты. Таким образом мы убиваем сразу целый косяк грызунов: у нас есть активный объект, свойства/методы которого доступны для использования и он же является прототипом («декларацией класса») для своих потомков. Очень отдаленно (ну о-о-о-очень отдаленно) такая структура напоминает статические классы.

Объекты которые есть всегда


Сразу после запуска интерпретатора вам доступны несколько «глобальных» объектов, пожалуй самые важные из них вот эти:
  • Lobby
  • Object

Первый объект хранит в себе рантайм и является, так сказать, почвой под ногами у выполняемого кода. Второй — базовый объект для клонирования, чаще всего первыми строками исходника на io бывают комментарии «SomeObject := Object clone».
То есть даже когда вы пишите вроде бы не «объектно», вы все-равно пишете объектно. Например код:
<font color="#9acd32">factorial</font> <font color="#8fbc8f">:=</font> <font color="#8b8378">method</font>(number,
  <font color="#8b8378">if</font>(<font color="#9acd32">number</font> <font color="#8fbc8f">==</font> 0,
    1,
    number <font color="#8fbc8f">*</font> factorial(number <font color="#8fbc8f">-</font> 1)
  )
)
factorial(5) <font color="#8b8378">print</font>

Создает вовсе не функцию факториал, он создает слот факториал в объекте Lobby.
Lobby является контекстным объектом, пока явно контекст не переключается на другой объект.

Немножко вуду


Объекты в io интроспективны, то есть вы можете копаться у них в кишках как вашей извращенной натуре только захочется, если у вас есть какой-то непонятный объект, вы всегда можете посмотреть чего у него внутре (печеньки неонка!).
<font color="#00ff00">Lobby</font> <font color="#8b8378">slotNames</font> <font color="#8b8378">print</font>

Это уже началось метапрограммирование, тема отдельной статьи, пока я только упомяну то, что вы можете «на лету» делать с объектами такие штуки, которые ни в одном немецком фильме не показывают.

Модульность


Может это и тема отдельной статьи, но пробежаться надо в любом случае. Конечно io модульный язык, иначе не могло быть просто потому, что не могло быть. Причем модульность в io сделана крайне прикольным образом, тут нет никаких import/include/require_once, тут все проще. Есть некий модуль Z_Importer, который загружается вместе с интерпретатором в память, как только вы пытаетесь использовать какой-либо объект не входящий в лексический обзор текущего файла, этот самый модуль ломится искать файл с именем объекта. Сначала в текущем каталоге, потом по каталогам библиотек (указываемым методом addSearchPath). Допустим классы Mushroom, Lenin и Man из первой статьи лежат в отдельных файлах. Как накормить мужика?
Mushroom <font color="#cd5c5c">//Достали грибочек из  Mushroom.io
</font>Lenin    <font color="#cd5c5c">//Достали Владимирильича из Lenin.io
</font>Man      <font color="#cd5c5c">//Достали мужыка из Man.io
</font>
Man eat(Mushroom)
Man state println

По-моему это самый дзэнский импортер из всех, которые я видел (:

Ну и все, пожалуй


Вроде бы это все, что нужно знать о объектной модели io, главное помнить про сообщения, но это уже совсем другая история (:

Ссылки


Если кому-то интересно что, где когда и как, можно почитать референс по io: http://iolanguage.com/scm/git/checkout/Io/docs/IoReference.html
А еще мы вчера наколбасили русскоязычный irc-канал про io: #io-ru@FreeNode, ждем заинтересовавшихся (:

P.S. У вас тут, между прочим, в минусах сидит один из знатоков io (А в догонку еще и разработчик StrokeDB) — oleganza, я хочу попросить, что бы он поправил меня или дополнил, если я где-то ошибся или чего-то недоговорил.

(Из моего блога)
Tags:
Hubs:
Total votes 46: ↑43 and ↓3 +40
Views 1.8K
Comments 72
Comments Comments 72