OberonCore https://forum.oberoncore.ru/ |
|
Расширение Oberon 2: утиные интерфейсы https://forum.oberoncore.ru/viewtopic.php?f=30&t=6131 |
Страница 1 из 5 |
Автор: | ilovb [ Воскресенье, 08 Октябрь, 2017 01:13 ] |
Заголовок сообщения: | Расширение Oberon 2: утиные интерфейсы |
Это просто идея из разряда "а что если?". Мне интересно ваше мнение. Имхо, добавить поддержку интерфейсов в Oberon 2 не сложно: 1. RECORD без полей считается абстрактной (aka интерфейс) Тип T = RECORD END совместим с любой записью, для которой имеются все методы T Размещать такие записи запрещено. Наследоваться от записи можно. 2. Методы для RECORD без полей считаются особыми. При загрузке модуля все такие методы собираются в одну глобальную таблицу: <номер метода> | <уникальная сигнатура> При добавлении каждого метода в таблицу если еще нет такой сигнатуры, то выдается новый номер и сигнатура добавляется в таблицу. 3. Таблицу методов в дескрипторе типов нужно дополнить номерами методов в глобальной таблице (если в глобальной таблице нет, то 0, например). Эти номера при загрузке модуля заполняются из глобальной таблицы. 4. Диспетчеризация выполняется очень просто: Допустим есть абстрактный тип A = RECORD END с методом Read() и наш конкретный тип R = RECORD f: FILE; END с методом Read() При присваивании или передаче R в A ничего не делается. Тут поведение остается как раньше. А вот при вызове любого метода у переменной типа A выполняется простой линейный поиск метода по номеру: Из таблицы методов типа A берется номер метода и ищется в таблице методов R. Если R является расширением A, то работает старый механизм. 5. ANYREC программист может определить себе сам как RECORD END без методов. Все остальное в языке остается без изменений. Какие грабли тут могут быть? ps Диспетчеризацию можно ускорить за счет памяти если присваивать типам и методам номера и хранить глобальную таблицу NxM, где N - количество типов записей реализующих абстрактные методы, а M - количество абстрактных методов. Для получения адреса метода m для типа n делаем t^[n, m] related: viewtopic.php?f=12&t=6127&p=102197#p102189 |
Автор: | Илья Ермаков [ Воскресенье, 08 Октябрь, 2017 02:41 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Столь ли нужна "утиность" по отдельным методам? Метод не является обычно полноценным интерфейсом. Интерфейс - это группа методов. В порядке бредогенерации, другой вариант: - связывание нескольких объектов вместе как граней "мультиобъекта", когда вы можете запросить грань другого типа. Поддержка: - рантайм у всех объектов вводит доп. указатель facets - кольцевой список связанных вместе объектов-граней. - Библиотечная процедура, условно, Facet(obj, needleFacetTypeTag). |
Автор: | Kemet [ Воскресенье, 08 Октябрь, 2017 06:13 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Да зачем сдались утиные интерфейсы? Нормальные интерфейсы нужны. |
Автор: | ilovb [ Воскресенье, 08 Октябрь, 2017 17:12 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Обычные интерфейсы не имеют никакого смысла. Вы либо будете делать иерархию наследования интерфейсов и столкнетесь с теми же проблемами, что и в классическом ООП. Либо вам придется делать что-то вроде множественного наследования. И при этом гибкость будет меньше чем у утиных интерфейсов. Это же очевидно. Вы не получите чистую абстракцию другим способом. Кроме того, предложенное - это дополнение к классическому ООП. Т.е. в языке будет полная свобода по реализации любых динамических вещей и при этом будет три уровня эффективности: 1. Статические методы (вернее обычные процедуры) 2. Динамические методы (обычные методы Oberon 2) 3. Абстрактные методы (интерфейсы) Фигачим в основном на уровне 2. Когда нужно чуть эффективнее, то спускаемся на уровень 1. Когда нужно чуть гибче, то поднимаемся на уровень 3. Да это блин идеальный язык будет. 2 Илья: Я думаю, что формула один метод == один интерфейс - это таки самое правильное понимание сути утиных интерфейсов. Это и объясняет всю их гибкость. Мы редуцируем обычные интерфейсы до элементарных с одним методом (хоть это и не очевидно по синтаксису). И сама по себе реализация метода интерфейса и есть заявка на поддержку. То, что в Go интерфейс объявляется с несколькими методами - это чисто оформительная штука для человека. Мне казалось, что это все понимают... Цитата: В порядке бредогенерации... Если честно, то слабо понял. Можешь немного развернуть мысль? |
Автор: | Илья Ермаков [ Воскресенье, 08 Октябрь, 2017 21:41 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Код: MODULE Objects; TYPE Object* = POINTER TO ABSTRACT RECORD facets-: Object (* кольцевой список связанных вместе граней мультиобъекта *) END; MODULE Stores; TYPE Store* = POINTER TO ABSTRACT RECORD (Obj.Object) END MODULE BioModels; TYPE Cell* = POINTER TO ABSTRACT RECORD (Obj.Object) END; (* Это кто-то из неизвестных биологов вводил свои типы для биомоделирования, но ничего не знал про Stores *) MODULE BioModelsImpl; (* А тут нам надо реализовать Cell так, чтобы поддержать ещё и хранимость *) TYPE Cell = POINTER TO RECORD (BioModels.Cell) ..... END; CellStore = POINTER TO RECORD (Stores.Store) END; PROCEDURE NewCell* (): BioModels.Cell; VAR c: Cell; cs: CellStore; BEGIN NEW(c); NEW(cs); Objects.JoinFacets(c, cs); RETURN c END NewCell; Использование: VAR c: BioModels.Cell; c := BioModelsImpl.New(); .... wr.WriteStore(c.Facet(<id типа Stores.Stores>)); -- оставим тут в стороне вопрос, как мы удобно идентифицируем id типа. У нас есть токены, например, - это будет постоянный глобальный объект-идентификатор. В стандартном ББ модуль может иметь глобальной переменной один раз взятый Meta.Item от нужного типа. Всё библиотечно и без проблем. В таком не всеобщем варианте я применяю, для каких-то отдельных типов. Ну а для универсального применения: этот базовый Object должен тогда быть, как бы, неявным (обеспечиваться рантаймом). Вы же не перепишете чужой абстрактный тип для наследования от своего базового Objects. И тут вопрос: можно насчитать несколько кандидатов на функции такого базового Object. И это всё - доп. память, которая навязывается каждому объекту. Другой вариант - что сама реализация списка не кладётся в базовый Object. А только окончательный модуль реализации кладёт в свои объекты поле статического RECORD-типа Objects.FacetsImpl. |
Автор: | Valery Solovey [ Воскресенье, 08 Октябрь, 2017 21:57 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
ilovb писал(а): При загрузке модуля все такие методы собираются в одну глобальную таблицу: "Собираются в одну таблицу" на этапе компиляции или исполнения?<номер метода> | <уникальная сигнатура> Глобальная таблица - это таблица внутри модуля или таблица на всё виртуальное адресное пространство? Если второе, то загрузка модулей может оказаться долгим процессом (если модуль - это единица загрузки). Цитата: <номер метода> | <уникальная сигнатура Если номера методов идут строго по порядку, то в этих номерах нет смысла. Нужен только массив уникальных сигнатур, а номером метода будет индекс в массиве.
|
Автор: | Valery Solovey [ Воскресенье, 08 Октябрь, 2017 21:59 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Kemet писал(а): Да зачем сдались утиные интерфейсы? Нормальные интерфейсы нужны. А какие интерфейсы нормальные? И почему эти интерфейсы не нормальные? |
Автор: | ilovb [ Воскресенье, 08 Октябрь, 2017 22:03 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Valery Solovey писал(а): Собираются в одну таблицу" на этапе компиляции или исполнения? Зависит от реализации. Если монолит, то на этапе компиляции. Если как BB, то на этапе исполнения. Valery Solovey писал(а): Глобальная таблица - это таблица внутри модуля или таблица на всё виртуальное адресное пространство? Если второе, то загрузка модулей может оказаться долгим процессом (если модуль - это единица загрузки). Одна на все вирт. пространство. Почему долгим? Из-за линейного поиска? Это надо проверять, но мне кажется на современных процессорах это смешное время будет. В любом случае можно придумать поисковую структуру данных под это дело. Valery Solovey писал(а): Если номера методов идут строго по порядку, то в этих номерах нет смысла. Нужен только массив уникальных сигнатур, а номером метода будет индекс в массиве. Согласен. Я просто как СУБДшник мыслю на автомате) |
Автор: | ilovb [ Воскресенье, 08 Октябрь, 2017 22:21 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Илья Ермаков писал(а): Всё библиотечно и без проблем. В таком не всеобщем варианте я применяю, для каких-то отдельных типов. Ну а для универсального применения: этот базовый Object должен тогда быть, как бы, неявным (обеспечиваться рантаймом). Вы же не перепишете чужой абстрактный тип для наследования от своего базового Objects. И тут вопрос: можно насчитать несколько кандидатов на функции такого базового Object. И это всё - доп. память, которая навязывается каждому объекту. Другой вариант - что сама реализация списка не кладётся в базовый Object. А только окончательный модуль реализации кладёт в свои объекты поле статического RECORD-типа Objects.FacetsImpl. Ну в целом идея понятна, но если честно это выглядит как 80% усилий ради 20% результата. Т.е. тебе тут явно пришлось бороться с классическим ООП вместо решения задачи. На Go это был бы ровно один метод для поддержки хранимости. Без всей этой архитектуры ради архитектуры. ps Хотя меня не покидает ощущение, что у тебя какая-то другая задача решается |
Автор: | Kemet [ Понедельник, 09 Октябрь, 2017 04:31 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Valery Solovey писал(а): Глобальная таблица - это таблица внутри модуля или таблица на всё виртуальное адресное пространство? В А2 в старом компиляторе была поддержка интерфейсов. Была она там для jvm изначально, но и в Активном Обероне была начальная недопиленая реализация. Для хранения интерфейсов использовалась двойная хеш-таблица (для ускорения ).
|
Автор: | Kemet [ Понедельник, 09 Октябрь, 2017 04:39 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Valery Solovey писал(а): Kemet писал(а): Да зачем сдались утиные интерфейсы? Нормальные интерфейсы нужны. А какие интерфейсы нормальные? И почему эти интерфейсы не нормальные? |
Автор: | ilovb [ Понедельник, 09 Октябрь, 2017 09:03 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Весь этот вброс комментировать не буду. Цитата: Динамические интерфейсы нужны там, где никакой проработки нет, а пишется по принципу, что вижу, то и пою Проработка чего? Продемонстрируй хоть пример этой проработки. |
Автор: | Trurl [ Понедельник, 09 Октябрь, 2017 09:12 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Valery Solovey писал(а): А какие интерфейсы нормальные? Пингвиньи же. |
Автор: | ilovb [ Понедельник, 09 Октябрь, 2017 09:19 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
"утиные интерфейсы" - это если что чисто мое словоблудие. Никто так вроде не говорит. |
Автор: | Kemet [ Понедельник, 09 Октябрь, 2017 13:24 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
ilovb писал(а): Весь этот вброс комментировать не буду. Цитата: Динамические интерфейсы нужны там, где никакой проработки нет, а пишется по принципу, что вижу, то и пою Проработка чего? Продемонстрируй хоть пример этой проработки. Да какой вброс? Просто иной взгляд на тему. Проработка иерархий, связей. Объект сам должен предоставлять возможные интерфейсы. И это должно быть определено на этапе компиляции. Нельзя по желанию делать из ежа бегемота только потому, что у ежа тоже 4 ноги и хвост, и они тоже могут ходить, бегать, лежать, спать, кушать радугу и какать бабочками. Но и у ежа и у бегемота есть сходные свойства, события, состояния, процессы. Это и нужно проанализировать и заняться проектированием. А херак херак и в продакшн это и есть динамические интерфейсы, когда думать не хочется и не можется, в песню спеть нужно. |
Автор: | ilovb [ Понедельник, 09 Октябрь, 2017 13:56 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Я не знаю как это воспринимают другие, но на мой взгляд, тот факт что можно рассматривать многих животных как нечто с четырьмя конечностями - это и есть обобщение (aka абстракция). Если кто-то вкладывает в слово "абстракция" что-то другое, то это его личная проблема, имхо. Давай я микролекцию тут прочитаю о сущности абстракции и абстрагирования (чую это давно уже надо было сделать, чтоб ссылаться): Абстракцию можно мыслить как результат некоторой функции абстрагирования. Пусть это будет F(x). Тогда абстракция - это y = F(x). Такая функция осуществляет редукцию объекта на в ходе. Т.е. одному y соответствует много x Пример1: x - это 3D модели животных. y - это значение перечисления (двуногое, четвероногое, безногое, неведомая хрень) Пример2: x - это картинки с изображением набора предметов (одних и тех же) y - это число, которое соответствует количеству предметов на картинке. И это не пространные рассуждения. F(x) - это вычислимая функция. x и y - это материальные объекты (электроны в оперативе, структуры мозга, почеркушки на бумаге, etc) Доступно объясняю? Если я хочу определить процедуру, которая будет заставлять четвероногое животное бежать галопом, то мне пофиг, что это за животное. Мне нужно только сигналы подавать в определенной последовательности на его 4 ноги. Если мне нужно подковать четырехногое животное, то я определю интерфейс чуть уже. Например, добавлю метод, получающий копыто с ноги. Если я хочу накормить животное, то мне пофиг, что это за животное. Мне от него нужно только понимание команды "Жри()" ))) Ну и как бы вроде наше мышление именно так и устроено. Разве нет? Разве добавление в программирование чего-то сверх этого не раздувание сложности? Товарищи, классическое ООП сделано так как сделано, не потому что это хорошая модель, а только лишь потому что это можно очень легко и эффективно сделать технически. Т.е. оно такое из-за ограничений технологии, а не по желанию создателей. Неужели вы это не понимаете? А вселенная не дура. Она дешево профит не продает. Какие нафиг иерархии, Kemet? Иерархия в Oberon-07 нужна только чтобы RECORD удобно разрезать технически на предка и потомка. Все. Точка. Это конкретная техника диктует иерархию. Иерархия - это досадная необходимость. А вы носитесь с ней как с граалем. Цитата: Это и нужно проанализировать и заняться проектированием Тут много кто мнит себя архитектором (включая меня конеш). Вот только выхлопа чет не видать. Цитата: Объект сам должен предоставлять возможные интерфейсы Я же писал выше, что 1 интерфейс == 1 метод. Что еще то нужно? Ты объявил метод - это и есть заявка на поддержку интерфейса. Если объявлять заявку на составные интерфейсы, то количество конфликтов интерфейсов будет расти по экспоненте относительно количества методов в интерфейсах. В то время как с элементарными интерфейсами конфликт только один - это совпадение имени при несовпадении параметров. Не поленюсь даже на пример: Есть интерфейс 1: X(), Y(), Z() Есть интерфейс 2: X(), Z(), Y() Они не совместимы! Чо буш делать если тебе нужно оба в твоем объекте? Полностью реализацию продублируешь? Или диспетчер запилишь? (т.е. оверхед как у утиных, но при этом нужны телодвижения при кодинге... и где выигрыш? ) |
Автор: | albobin [ Понедельник, 09 Октябрь, 2017 14:48 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Наверное имеет смысл покопаться в уже придуманном как в ETH, так и у выходцев оттуда, например у Франца с его 'Lagoon'ой. Тема уже промелькнула здесь на форуме, но ссылки, возможно, уже устарели. |
Автор: | Trurl [ Понедельник, 09 Октябрь, 2017 15:08 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
ilovb писал(а): Я не знаю как это воспринимают другие, но на мой взгляд, тот факт что можно рассматривать многих животных как нечто с четырьмя конечностями - это и есть обобщение (aka абстракция). Напомнило старую шутку про обобщенную корову |
Автор: | ilovb [ Понедельник, 09 Октябрь, 2017 15:15 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
Ну тык так и есть |
Автор: | Trurl [ Понедельник, 09 Октябрь, 2017 15:22 ] |
Заголовок сообщения: | Re: Расширение Oberon 2: утиные интерфейсы |
ilovb писал(а): Если я хочу накормить животное, то мне пофиг, что это за животное. Мне от него нужно только понимание команды "Жри()" ))) Есть проблема. Команду Run могут понимать Duck, Wombat и DiskFormatter. |
Страница 1 из 5 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |