Здравствуйте, c-smile, Вы писали:
E>>В Ruby для похожих целей есть классы Struct, OpenStruct. А прямо в описании стандартного класса OptionParser приводится пример непосредственного использования OpenStruct ...
CS>Struct и OpenStruct понятны. CS>Непонятно другое: зачем надо было делать hash map и скажем объект разными сущностями.
Чесно говоря не понял, что ты хотел сказать
Hash -- это объект в Ruby (как и все остальное), просто для него встроили в язык еще один (даже не один) формат записи:
Экземпляр Hash для создания объекта OpenStruct нужен только для того, чтобы задать элементы вместе со своими начальными значениями. Если этого не сделать, то элементы в OpenStruct будут инициализироваться значением nil:
Если же ты о том, что для поддержки prototype-based programming в Ruby не было сделано специального синтаксиса, то это как раз тот случай, когда незачем вводить в язык то, что можно сделать библиотекой. OpenStruct -- это всего лишь один класс в стандартной библиотеке (файл ostruct.rb из 146 строк, в которые входят и описания и метод inspect и методы marshal). А вся магия OpenStruct строится на основе фундаментальных возможностей языка: метод method_missing для перехвата не реализованных объектом методов и динамическое расширение объекта новыми методами в run-time.
CS>ПММ, в JS это красивее сделано (если забыть про кашу с __proto__).
А ПММ -- это как расшифровывается ("по-моему мнению" или "поверь моему мнению")?
Кстати, Ruby-новый синтаксис позволяет записывать еще компактнее:
[...]
ЗХ>3. В "истинно прототипном" программировании, новый объект, созданный путем клонирования, "забывает" о "родителе". Тем не менее, и в Self, и в JS различными способами имитируется "что-то вроде наследования" ("я помню о своем прототипе, и если не знаю как обработать сообщение, прошу его это сделать"). Из чего можно сделать определенные выводы. И я от них не удержусь!
Точнее, изначально в Self все видимо было так, как я пытался рассказать ("объект не помнит прототипа" => "нужно что-то вроде наследования" => "объект помнит прототип"). Впоследствии оказалось, что сама по себе идея "объект, который может обработать сообщения, которые я не могу" — имеет свои прелести.
И сегодняшнее "прототипное программирование" означает, в общем, 2 практически ортогональные идеи
1. все объекты получаются клонированием существующих (как и было сказано)
2. у каждого объекта может быть любое количество "прототипов" — тех, кому делегируется обработка неизвестных сообщений.
Если к (2) добавить возможность динамической смены прототипа (а она есть во всех прототипных языках), то получается много интересных фенечек. Например, все в том же Io понятие прототипа успешно заменяет lexical scope ("какой прототип получает все сообщения в данном контексте"). Соответственно, "выполнение метода данного объекта" == "выполнение кода метода с prototype = this".
ЗЫ: Вообще, оч.рекомендую посмотреть на Io для общего развития — концепций там кот наплакал, а результат получился интереснейший.
Например, идея асинхронной посылки метода с возвращением будущего результата:
result := Object test #синхронная посылка метода, ждет пока метод выполнится и возвращает результат
futureResult := Object @test #асинхронная посылка метода, возвращает управление немедленно, и возвращает "будущий результат"
Радость в том, что с "будущим результатом" можно работать прозрачно — посылать ему сообщения, и когда метод test закончит выполнение, во futureResult будет помещен реальный результат, и ему будут переданы все эти сообщения.
Здравствуйте, eao197, Вы писали:
E>Здравствуйте, c-smile, Вы писали:
E>>>В Ruby для похожих целей есть классы Struct, OpenStruct. А прямо в описании стандартного класса OptionParser приводится пример непосредственного использования OpenStruct ...
CS>>Struct и OpenStruct понятны. CS>>Непонятно другое: зачем надо было делать hash map и скажем объект разными сущностями.
E>Чесно говоря не понял, что ты хотел сказать
Он хотел сказать, что в prototype-based языках объект — это всего лишь хэш именованных свойств. Причем методы — такие же свойства объекта как и данные. В Руби это не так.
Здравствуйте, Зверёк Харьковский, Вы писали:
CS>>>Непонятно другое: зачем надо было делать hash map и скажем объект разными сущностями.
E>>Чесно говоря не понял, что ты хотел сказать
ЗХ>Он хотел сказать, что в prototype-based языках объект — это всего лишь хэш именованных свойств. Причем методы — такие же свойства объекта как и данные. В Руби это не так.
С некоторой натяжкой можно сказать, что в Ruby то же самое.
Однако мне интересно другое -- для пользователя языка какая разница, как интерпритатор языка реализует объект (в виде хэша, в виде набора хэшей). Пользователю нужны всего лишь высокоуровневые операции модификации и клонирования объекта в run-time.
SObjectizer: <микро>Агентно-ориентированное программирование на C++.
Здравствуйте, eao197, Вы писали:
CS>>>>Непонятно другое: зачем надо было делать hash map и скажем объект разными сущностями.
E>>>Чесно говоря не понял, что ты хотел сказать
ЗХ>>Он хотел сказать, что в prototype-based языках объект — это всего лишь хэш именованных свойств. Причем методы — такие же свойства объекта как и данные. В Руби это не так.
E>С некоторой натяжкой можно сказать, что в Ruby то же самое. E>Однако мне интересно другое -- для пользователя языка какая разница, как интерпритатор языка реализует объект (в виде хэша, в виде набора хэшей). Пользователю нужны всего лишь высокоуровневые операции модификации и клонирования объекта в run-time.
В том и дело, пользователю важно не то, что интерпретатор внутри думает, а что снаружи видно. Т.е. если весь объект представляетс как хэш, то...
Т.е. количество абстракций уменьшается: есть тип данных "функция" и все. Руби, по сравнению с этим, намного более многословен, и "присвоить значение переменной объекта" выглядит совсем не так, как "определить метод объекта".
С другой стороны (это уже пошел ответ на вопрос c-smile "зачем надо было делать hash map и скажем объект разными сущностями"), в Руби вообще нет концепции "данных объекта, видимых снаружи".
Т.е., когда мы пишем
x.some_value = 5
Это не
x.set_value("some_value", 5)
а
x.call_method("some_value=", 5)
А уж как там объект реализует метод some_value= (и будет ли он симметричен методу-геттеру some_value) — личное дело объекта.
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>В том и дело, пользователю важно не то, что интерпретатор внутри думает, а что снаружи видно. Т.е. если весь объект представляетс как хэш, то... ЗХ>
Ты бы лучше чем в пятисотом колене все это писать написал бы статейку где и изложил бы все по полочкам. И людям было бы интересно, и сам бы оценок заработал бы.
... << RSDN@Home 1.2.0 alpha rev. 637>>
Есть логика намерений и логика обстоятельств, последняя всегда сильнее.
Токо вот не умею я так ярко преподнести материал. Поэтому вместо того, чтобы сконцентрировать внимание на плюсах, сконцентрировался на реализации. И завяз...
Зато по ходу дела придумал "репликатор методов". Если кому интересно, но из названия непонятно — могу рассказать:
Есть такая проблема.
В некотором проекте некоторой компании жила-была некоторая реализация алгоритма.
Проект решили расширить, углубить и проинтегрировать. Начали естес.но рефакторить. и давай вытаскивать реализации.
А они, подлые, методами классов сделаны.
На сях та оно понятна, функций натырил и рад. А тут плюсы — надо классы тырить, а в них злая база да гуй некислый.
Шо делать?
Вот тут на помощь и должон приидти "репликатор методов".
Как он работает?
Во первых, это дело работает тесно с ИДЕ.
Подсовываешь ему проект и выбираешь некоторый метод некоторого класса.
И ИДЕ с репликатором вытаскивает этот метод либо в отдельную функцию, либо делает его методом другого класса.
При этом она ориентируется на названия, типы и аттрибуты членов классов.
Если каких-то членов нехватает, то создаётся реквест на члены.
По этому реквесту ИДЕ может автоматом добавить к новому проекту необходимые свойства и методы.
Короче репликатор предназначен для перетаскивания методов со всеми зависимостями из проекта в проект.
Что из этого можно сделать? Я так скромно полагаю, что это полностью изменит представления о программировании в мэйнстрим в ближайшие 10 лет.
Почему?
А потому, что функциональный (читаем алгоритмический) код станет очень просто заимствовать.
А код декларативный будет выстраиваться полуавтоматически.
WR>Токо вот не умею я так ярко преподнести материал. Поэтому вместо того, чтобы сконцентрировать внимание на плюсах, сконцентрировался на реализации. И завяз...
Дык... Prior art надо изучать, ага?
WR>Зато по ходу дела придумал "репликатор методов". Если кому интересно, но из названия непонятно — могу рассказать:
[...]
Идея занятная. И таки похоже связанная с прототипностью.
Потому как в статье на которую я уже ссылался (реализация прототипов на Руби), была похожая мысль, названная "переносом генов". Вот код:
#создаем персону-европейку
nancy_cartwright = a_person.clone
nancy_cartwright.first_name = "Nancy"
nancy_cartwright.name = "Cartwright"#создаем персону-японку
hayashibara_megumi = a_person.clone
hayashibara_megumi.first_name = "Megumi"
hayashibara_megumi.name = "Hayashibara"#и определяем для нее "японский" метод преобразования имени в строкуdef hayashibara_megumi.to_s
"#{name} #{first_name}"end#создаем еще одну японку
inoue_kikuko = a_person.clone
inoue_kikuko.first_name = "Kikuko"
inoue_kikuko.name = "Inoue"#откусываем метод от одной японки
japanese_to_s = hayashibara_megumi.copy_gene(:to_s)
#и приклеиваем его к другой
inoue_kikuko.use_gene japanese_to_s
Соотношение реализации этого способа (динамическое копирование методов) с твоим (копирование кода методов при поддержке IDE) демонстрирует глубокое идеологическое различие между статикой и динамикой, и теми кто их использует (пусть горит флейм! Chanky bacon!)
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Соотношение реализации этого способа (динамическое копирование методов) с твоим (копирование кода методов при поддержке IDE) демонстрирует глубокое идеологическое различие между статикой и динамикой, и теми кто их использует (пусть горит флейм! Chanky bacon!)
Имхо. Различие в целях. я описал конкретную ситуацию, когда репликация методов может быть использованна.
Причём она отличается от простого копирования тем, что может модифицировать идентификаторы зависимых членов и методов, тем самым подстраиваясь под новый проект.
В твоём примере назначение копирования (опс! или клонирования) метода(гена) не совсем понятно.
Кстати.
Терминология "генов" наводит на очень интересные ассоциации.
Интересен такой вопрос:
Как в прототипной парадигме будет выглядеть фабрика? — Женская особь!
Продолжу немного издалека.
Недавно читал гм, Веллера. Так вот. У него есть такая интересная мысль — что в природе, полюсное отличие (к примеру) мужского и женского начал, приводит к возникновению "разности потенциалов". Что сказывается на увеличении потенциальной энергии. Затем человек выдумывает всевозможные табу, чтобы эту энергию удерживать. А сейчас мы видим, как европейская цивилизация ломает все табу, через распространение либеральной философии. И вся многовековая потенциальная энергия различных запретов превращается в кинетическую энергию научно-технического прогресса.
Теперь посмотрим — что есть парадигма программирования, язык. Это набор соглашений, правил, запретов.
Что мы ожидаем в программировании? Так или иначе — снятие запретов. Но не преждевременно, как это случилось с языком D.
Я раньше очень сердился на комитет отвечающий за принятие стандартов на с++, за то, что они годами ничего не делают. А теперь понимаю — правильно. Надо чтобы разность потенциалов выросла. И тогда...
Здравствуйте, WoldemaR, Вы писали:
WR>Есть такая проблема. WR>В некотором проекте некоторой компании жила-была некоторая реализация алгоритма. WR>Проект решили расширить, углубить и проинтегрировать. Начали естес.но рефакторить. и давай вытаскивать реализации. WR>А они, подлые, методами классов сделаны. WR>На сях та оно понятна, функций натырил и рад. А тут плюсы — надо классы тырить, а в них злая база да гуй некислый.
Так это баги дизайна.
Надо делать так, чтобы независимые сущности работали независимо.
Тем более если это C++ где есть множественное наследование и шаблоны, на которых можно наваять Policy-based design.
WR>Шо делать?
WR>Вот тут на помощь и должон приидти "репликатор методов". WR>Как он работает? WR>Во первых, это дело работает тесно с ИДЕ. WR>Подсовываешь ему проект и выбираешь некоторый метод некоторого класса. WR>И ИДЕ с репликатором вытаскивает этот метод либо в отдельную функцию, либо делает его методом другого класса. WR>При этом она ориентируется на названия, типы и аттрибуты членов классов. WR>Если каких-то членов нехватает, то создаётся реквест на члены. WR>По этому реквесту ИДЕ может автоматом добавить к новому проекту необходимые свойства и методы.
Да это то можно сделать (развитие рефакторинга), какие вопросы.
Только в новом проекте тогда получится такая же помойка, что и в старом.
Даже хуже поскольку помимо старого мяса(кода) добавится новое.
В общем как мне кажется важен грамотный дизайн (да хотя бы тот же MVC или MVP
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>1. Прототипное программирование — такой способ программирования, при котором новые объекты создаются не как экземпляры "классов", а как клоны существующих объектов; объекты могут изменяться на лету (например, добавлять методы); никаких концепций, кроме "объекты и сообщения" не существует — нет классов, нет наследования, нет синглетонов, нет ложки. Прототипное программирование — не "такое криво сделанное ООП", а другая парадигма.
Это можно рассматривать как другую парадигму, если начать работать непосредственно с объектной модедью. Не с классами, но с экземплярами, можно вообще без классов.
Первая версия нашей технологии FloraWare не содержала аппарата классов и типов, мы даже ввели понятие "класс одного экземпляра". Все было построено на копировании экземпляров. Но львина доля этого копирования приходиолась на рабату редакторов.
Здравствуйте, WoldemaR, Вы писали:
WR>Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>>А тема, скажем прямо, интересная.
WR>Согласен. Интересная. Я её уже примерно полгода назад придумал. WR>http://www.rsdn.ru/Forum/Message.aspx?mid=1593869
А мы 10 лет назад придумали. Хранить все объекты в дереве. Там же хранить и описатели классов. В дереве собирается объектная модель. Тут тебе и Диаграмма классов и Диаграмма объектов. Так как описатель класса в одном дереве с экземплярам, то мы имеем и владение и метаинформацию.
Здравствуйте, Андрей Хропов, Вы писали:
АХ>Здравствуйте, WoldemaR, Вы писали:
WR>>Есть такая проблема. WR>>В некотором проекте некоторой компании жила-была некоторая реализация алгоритма. WR>>Проект решили расширить, углубить и проинтегрировать. Начали естес.но рефакторить. и давай вытаскивать реализации. WR>>А они, подлые, методами классов сделаны. WR>>На сях та оно понятна, функций натырил и рад. А тут плюсы — надо классы тырить, а в них злая база да гуй некислый. АХ>Так это баги дизайна.
...
Я имею на руках конкретный проект. И сужу исходя из этого.
Если подойти к проектированию формально, то изоляция некоторых методов обработки приведёт к функциям из 20 аргументов. Что ИМХО — зло большее, это уже никаким дизайном не исправишь.
Так что не спеши заочно судить о дизайне.
Интересно, что же делать в яваскрипте? Вроде бы он предлагает средства для реализации обоих подходов: и делегирования, и клонирования.
Вероятно, реализовывать это можно: (может быть это и ошибочное мнение)
Здравствуйте, Зверёк Харьковский, Вы писали:
ЗХ>Поздравляю, Шарик! Ты меня окончательно запутал! ЗХ>Коль скоро ты уже сделал из prototype-based языка class-based, зачем тебе то, с чего ты начал обсуждение? Вот это вот: ЗХ>
ЗХ>//зачем тебе
ЗХ>var P = { prototype:Person, name:"Joe", phone:[0,8,2] };
ЗХ>//если у тебя уже есть?
ЗХ>var P = new Person();
ЗХ>
ЗХ>ы???
Есть случаи когда нужны типы данных с переменным составом полей в принципе.
Хотя чем больше я думаю про это тем мне это меньше нравится.
В такой конструкции:
var P = { prototype:Person, name:"Joe", phone:[0,8,2] };
надо что-то делать с конструктором.
лучше написать:
function Person.create( record ) { record.prototype = Person; record.date = new Date(); }
var P = Person.create({ name:"Joe", phone:[0,8,2] });
Здравствуйте, VladD2, Вы писали:
VD>Здравствуйте, c-smile, Вы писали:
VD>Ты бы лучше чем в пятисотом колене все это писать написал бы статейку где и изложил бы все по полочкам. И людям было бы интересно, и сам бы оценок заработал бы.
Эх, Влад, у меня очередь статей на три года вперед. Доки, спеки и прочая.
Я бы уже такой что заплаптил кому только глаза бы мои этот эпистолярный жанр не видели...
Здравствуйте, WoldemaR, Вы писали:
WR>Я имею на руках конкретный проект. И сужу исходя из этого. WR>Если подойти к проектированию формально, то изоляция некоторых методов обработки приведёт к функциям из 20 аргументов. Что ИМХО — зло большее, это уже никаким дизайном не исправишь. WR>Так что не спеши заочно судить о дизайне.
Не говорю о конкретном проекте, но ИМХО, отца русской демократии мог бы спасти рефакторинг Introduce Parameter Object — и никаких 20 параметров...
Здравствуйте, Gajdalager, Вы писали:
G>Здравствуйте, WoldemaR, Вы писали:
WR>>Я имею на руках конкретный проект. И сужу исходя из этого. WR>>Если подойти к проектированию формально, то изоляция некоторых методов обработки приведёт к функциям из 20 аргументов. Что ИМХО — зло большее, это уже никаким дизайном не исправишь. WR>>Так что не спеши заочно судить о дизайне.
G>Не говорю о конкретном проекте, но ИМХО, отца русской демократии мог бы спасти рефакторинг Introduce Parameter Object — и никаких 20 параметров...
Слушай, ты конечно прав, но ты не в теме совершенно.
Посмотри о чём я до этого говорил, а лучше — расслабься.
Здравствуйте, WoldemaR, Вы писали:
WR>Я имею на руках конкретный проект. И сужу исходя из этого.
Да это понятно, что дизайн лучше сначала прямой делать,
чем потом пытаться уже работающую вещь править.
Тут только рефакторинг и юнит/регрессионные-тесты в помощь.
WR>Если подойти к проектированию формально, то изоляция некоторых методов обработки приведёт к функциям из 20 аргументов.
Ужас какой! Ну тут два пути —
1) Зачем так много аргументов — не слишком ли много эта функция на себя берет. Лучше разбить на несколько.
2) Объединить аргументы в несколько структур/классов.
WR> Что ИМХО — зло большее, это уже никаким дизайном не исправишь.
Функции с 20 аргументами — это тоже плохой дизайн.