OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Понедельник, 11 Декабрь, 2017 08:44

Часовой пояс: UTC + 3 часа




Начать новую тему Ответить на тему  [ Сообщений: 93 ]  На страницу 1, 2, 3, 4, 5  След.
Автор Сообщение
СообщениеДобавлено: Воскресенье, 08 Октябрь, 2017 01:13 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1427
Это просто идея из разряда "а что если?".
Мне интересно ваше мнение.

Имхо, добавить поддержку интерфейсов в 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 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 8880
Откуда: Россия, Орёл
Столь ли нужна "утиность" по отдельным методам?

Метод не является обычно полноценным интерфейсом.

Интерфейс - это группа методов.

В порядке бредогенерации, другой вариант:

- связывание нескольких объектов вместе как граней "мультиобъекта", когда вы можете запросить грань другого типа.

Поддержка:
- рантайм у всех объектов вводит доп. указатель facets - кольцевой список связанных вместе объектов-граней.
- Библиотечная процедура, условно, Facet(obj, needleFacetTypeTag).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 08 Октябрь, 2017 06:13 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 410
Да зачем сдались утиные интерфейсы? Нормальные интерфейсы нужны.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 08 Октябрь, 2017 17:12 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1427
Обычные интерфейсы не имеют никакого смысла.
Вы либо будете делать иерархию наследования интерфейсов и столкнетесь с теми же проблемами, что и в классическом ООП.
Либо вам придется делать что-то вроде множественного наследования. И при этом гибкость будет меньше чем у утиных интерфейсов.
Это же очевидно. Вы не получите чистую абстракцию другим способом.

Кроме того, предложенное - это дополнение к классическому ООП.
Т.е. в языке будет полная свобода по реализации любых динамических вещей и при этом будет три уровня эффективности:
1. Статические методы (вернее обычные процедуры)
2. Динамические методы (обычные методы Oberon 2)
3. Абстрактные методы (интерфейсы)

Фигачим в основном на уровне 2. Когда нужно чуть эффективнее, то спускаемся на уровень 1. Когда нужно чуть гибче, то поднимаемся на уровень 3. Да это блин идеальный язык будет.

2 Илья:
Я думаю, что формула один метод == один интерфейс - это таки самое правильное понимание сути утиных интерфейсов.
Это и объясняет всю их гибкость. Мы редуцируем обычные интерфейсы до элементарных с одним методом (хоть это и не очевидно по синтаксису). И сама по себе реализация метода интерфейса и есть заявка на поддержку. То, что в Go интерфейс объявляется с несколькими методами - это чисто оформительная штука для человека.
Мне казалось, что это все понимают... :?

Цитата:
В порядке бредогенерации...

Если честно, то слабо понял. Можешь немного развернуть мысль?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 08 Октябрь, 2017 21:41 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 8880
Откуда: Россия, Орёл
Код:
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.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 08 Октябрь, 2017 21:57 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1526
Откуда: Беларусь, Минск
ilovb писал(а):
При загрузке модуля все такие методы собираются в одну глобальную таблицу:
<номер метода> | <уникальная сигнатура>
"Собираются в одну таблицу" на этапе компиляции или исполнения?

Глобальная таблица - это таблица внутри модуля или таблица на всё виртуальное адресное пространство?
Если второе, то загрузка модулей может оказаться долгим процессом (если модуль - это единица загрузки).

Цитата:
<номер метода> | <уникальная сигнатура
Если номера методов идут строго по порядку, то в этих номерах нет смысла. Нужен только массив уникальных сигнатур, а номером метода будет индекс в массиве.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 08 Октябрь, 2017 21:59 

Зарегистрирован: Понедельник, 30 Июль, 2007 10:53
Сообщения: 1526
Откуда: Беларусь, Минск
Kemet писал(а):
Да зачем сдались утиные интерфейсы? Нормальные интерфейсы нужны.

А какие интерфейсы нормальные? И почему эти интерфейсы не нормальные?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 08 Октябрь, 2017 22:03 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1427
Valery Solovey писал(а):
Собираются в одну таблицу" на этапе компиляции или исполнения?

Зависит от реализации. Если монолит, то на этапе компиляции. Если как BB, то на этапе исполнения.

Valery Solovey писал(а):
Глобальная таблица - это таблица внутри модуля или таблица на всё виртуальное адресное пространство?
Если второе, то загрузка модулей может оказаться долгим процессом (если модуль - это единица загрузки).

Одна на все вирт. пространство. Почему долгим? Из-за линейного поиска?
Это надо проверять, но мне кажется на современных процессорах это смешное время будет.
В любом случае можно придумать поисковую структуру данных под это дело.

Valery Solovey писал(а):
Если номера методов идут строго по порядку, то в этих номерах нет смысла. Нужен только массив уникальных сигнатур, а номером метода будет индекс в массиве.

Согласен. Я просто как СУБДшник мыслю на автомате)


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Воскресенье, 08 Октябрь, 2017 22:21 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1427
Илья Ермаков писал(а):
Всё библиотечно и без проблем.
В таком не всеобщем варианте я применяю, для каких-то отдельных типов.

Ну а для универсального применения: этот базовый Object должен тогда быть, как бы, неявным (обеспечиваться рантаймом).
Вы же не перепишете чужой абстрактный тип для наследования от своего базового Objects.
И тут вопрос: можно насчитать несколько кандидатов на функции такого базового Object. И это всё - доп. память, которая навязывается каждому объекту. Другой вариант - что сама реализация списка не кладётся в базовый Object. А только окончательный модуль реализации кладёт в свои объекты поле статического RECORD-типа Objects.FacetsImpl.


Ну в целом идея понятна, но если честно это выглядит как 80% усилий ради 20% результата.
Т.е. тебе тут явно пришлось бороться с классическим ООП вместо решения задачи.
На Go это был бы ровно один метод для поддержки хранимости. Без всей этой архитектуры ради архитектуры.

ps Хотя меня не покидает ощущение, что у тебя какая-то другая задача решается


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 04:31 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 410
Valery Solovey писал(а):
Глобальная таблица - это таблица внутри модуля или таблица на всё виртуальное адресное пространство?
В А2 в старом компиляторе была поддержка интерфейсов. Была она там для jvm изначально, но и в Активном Обероне была начальная недопиленая реализация. Для хранения интерфейсов использовалась двойная хеш-таблица (для ускорения ).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 04:39 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 410
Valery Solovey писал(а):
Kemet писал(а):
Да зачем сдались утиные интерфейсы? Нормальные интерфейсы нужны.

А какие интерфейсы нормальные? И почему эти интерфейсы не нормальные?
Нормальные интерфейсы - статические. Хорошо, когда поддерживается множественное наследование интерфейсов. С динамическими интерфейсами получается такое неструктурированное дерьмецо, просто жуть. Каждый альтернативно одаренный считает своим долгов впихнуть свое видение иерархии интерфейсов. И вдруг, другой такой же одаренный меняет на каком-то уровне своё видение и фсё, большой северный зверёк прокрался в ваши связанные проекты. Очень сложно ориентироваться в таком коде. Динамические интерфейсы нужны там, где никакой проработки нет, а пишется по принципу, что вижу, то и пою. Да и такая всеобщая каша превращается в обычную неструктурированную дрянь. Потому что винегрет , борщ и водка хороши по отдельности, но если их смешать - помои, однако, получатся.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 09:03 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1427
Весь этот вброс комментировать не буду.

Цитата:
Динамические интерфейсы нужны там, где никакой проработки нет, а пишется по принципу, что вижу, то и пою

Проработка чего? Продемонстрируй хоть пример этой проработки.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 09:12 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1010
Valery Solovey писал(а):
А какие интерфейсы нормальные?

Пингвиньи же.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 09:19 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1427
:D
"утиные интерфейсы" - это если что чисто мое словоблудие. Никто так вроде не говорит.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 13:24 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 410
ilovb писал(а):
Весь этот вброс комментировать не буду.

Цитата:
Динамические интерфейсы нужны там, где никакой проработки нет, а пишется по принципу, что вижу, то и пою

Проработка чего? Продемонстрируй хоть пример этой проработки.

Да какой вброс? Просто иной взгляд на тему.
Проработка иерархий, связей. Объект сам должен предоставлять возможные интерфейсы. И это должно быть определено на этапе компиляции. Нельзя по желанию делать из ежа бегемота только потому, что у ежа тоже 4 ноги и хвост, и они тоже могут ходить, бегать, лежать, спать, кушать радугу и какать бабочками. Но и у ежа и у бегемота есть сходные свойства, события, состояния, процессы. Это и нужно проанализировать и заняться проектированием. А херак херак и в продакшн это и есть динамические интерфейсы, когда думать не хочется и не можется, в песню спеть нужно.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 13:56 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1427
Я не знаю как это воспринимают другие, но на мой взгляд, тот факт что можно рассматривать многих животных как нечто с четырьмя конечностями - это и есть обобщение (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()
Они не совместимы! Чо буш делать если тебе нужно оба в твоем объекте? Полностью реализацию продублируешь?
Или диспетчер запилишь? (т.е. оверхед как у утиных, но при этом нужны телодвижения при кодинге... и где выигрыш? :? )


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 14:48 

Зарегистрирован: Пятница, 20 Июль, 2007 17:26
Сообщения: 656
Откуда: Псков
Наверное имеет смысл покопаться в уже придуманном как в ETH, так и у выходцев оттуда, например у Франца с его 'Lagoon'ой. Тема уже промелькнула здесь на форуме, но ссылки, возможно, уже устарели.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 15:08 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1010
ilovb писал(а):
Я не знаю как это воспринимают другие, но на мой взгляд, тот факт что можно рассматривать многих животных как нечто с четырьмя конечностями - это и есть обобщение (aka абстракция).

Напомнило старую шутку про обобщенную корову
Изображение


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 15:15 

Зарегистрирован: Вторник, 30 Июнь, 2009 14:58
Сообщения: 1427
:lol:
Ну тык так и есть :D


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Понедельник, 09 Октябрь, 2017 15:22 

Зарегистрирован: Понедельник, 28 Ноябрь, 2005 10:28
Сообщения: 1010
ilovb писал(а):
Если я хочу накормить животное, то мне пофиг, что это за животное. Мне от него нужно только понимание команды "Жри()" )))

Есть проблема. Команду Run могут понимать Duck, Wombat и DiskFormatter.


Вернуться к началу
 Профиль  
 
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 93 ]  На страницу 1, 2, 3, 4, 5  След.

Часовой пояс: UTC + 3 часа


Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Вся информация, размещаемая участниками на конференции (тексты сообщений, вложения и пр.) © 2005-2017, участники конференции «OberonCore», если специально не оговорено иное.
Администрация не несет ответственности за мнения, стиль и достоверность высказываний участников, равно как и за безопасность материалов, предоставляемых участниками во вложениях.
Без разрешения участников и ссылки на конференцию «OberonCore» любое воспроизведение и/или копирование высказываний полностью и/или по частям запрещено.
Powered by phpBB® Forum Software © phpBB Group
Русская поддержка phpBB