OberonCore
https://forum.oberoncore.ru/

Процедурные типы в Обероне
https://forum.oberoncore.ru/viewtopic.php?f=30&t=593
Страница 1 из 2

Автор:  GameHunter [ Воскресенье, 29 Июль, 2007 23:41 ]
Заголовок сообщения:  Процедурные типы в Обероне

Уважаемые специалисты,
Я вожусь с обероном (XDS), и вот с какой трудностью столкнулся:
нужно применить некий алгоритм к нескольким связаннам процедурам.
В Делфи это делается очень просто:

Код:
type
  proc = function (x,y: single): single of object;

Procedure Algorithm (p: proc);
  begin
    ...
  end;


В Обероне связанные процедуры нельзя присваивать процедурным переменным.
Что же делать, чтобы не дублировать код Algorithm для каждой процедуры?

Можно, конечно, оформить Algorithm в виде записи, а её параметр в виде
связянной процедуры. В таком случае придётся расширять эту запись каждый раз,
когда надо применить Algorithm для какой-то процедуры, это не удобно.
Не может ли кто-нибудь подсказать более изящное решение?

И ещё: в Делфи приведённую процедуру Algorithm можно было вызывать с обычной процедурой
объекта, а не только с виртуальной. В Обероне аналог обычной процедуры объекта
- это процедура с параметром типа запись. И опять-таки встаёт проблема,
как такой вызов оформить безразлично к типу записи?

С уважением,
GH.

Автор:  Илья Ермаков [ Понедельник, 30 Июль, 2007 12:37 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

Давайте глянем на контекст задачи....
Дело в том, что в случае отсутствия в языке некоторого средства (делегаты, кстати, они водятся в Активном Обероне...) лучше думать не о его эмуляции, а о выражении своей задачи через другие средства.
В частности, подозреваю, что поможет разбиение ответственности одного большого объекта на более мелкие (например, Courier-Rider..), тогда алгоритмы получают не методы-делегаты, а объекты-курьеры...

В общем, давайте пример контекста :-)

Автор:  GameHunter [ Понедельник, 30 Июль, 2007 14:19 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

Задача такая: решить 2-мерное уравнение в частных производных в прямоугольной области.
Коэффициенты при различных производных - функции координат, их 6
штук. Ещё 12 функций определяют граничные условия.
Для решения задачия я создаю запись, коэффициенты и граничные условия
оформляю как связанные процедуры. Потом при постановке конкретной задачи
я расширяю запись и конкретезирую все функции.

Перед решением я все коэффициенты табулирую во внутренние переменные записи.
Это, собственно, и есть тот Algorithm, который я применяю к связанным процедурам
- двум десяткам штук.

Не могли бы вы в кратце объяснить, что такое Courier-Rider, или дать ссылку
на ресурс, где это описывается.

Автор:  Илья Ермаков [ Понедельник, 30 Июль, 2007 14:35 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

Про Courier-Rider - паттерн "носитель-курьер", можно почитать в руководстве Блекбокса, главу 3 (кажется, 3) - про архитектурные приемы. Либо в классической книге Гаммы "Патерны объектно-ориентированного проектирования", издавалась Питером в 200.. г, можно найти электронно в интернете.
(Однако тут оно ни к чему особо, я упомянул это просто как пример, как путем разбиения на мелкие типы избегается необходимость делегатов к "жирным" объектам).

У Вас всё вроде бы гораздо проще... Зачем фанатичная ООП-изация там, где она не нужна?
Функция-коэффициент самодостаточна? Она не обращается к полям той записи, с которой Вы её связываете? Тогда зачем её связывать?
Если хотите иметь RECORD с "описанием задачи", опишите его с процедурными полями:
TYPE
Fun2* = PROCEDURE (x, y: REAL): REAL;
Equation* = RECORD
k1*, k2*, ...: Fun2
END;

Далее в месте решения описываете обычными процедурами коэффициенты, заносите указатели этих процедур в RECORD, отдаёте RECORD алгоритму.
Только результат табулирования лучше возвращать отдельным типом, а не полями того же RECORD... Пусть будут отдельные типы: функция двух переменных, описание задачи в частных производных, табулированное представление задачи в частных производных... Пилите на мелкие независимые типы.

Для большинства простых задач представления функции как PROCEDURE-типа достаточно.
В серьезных мат. библиотеках функции представляются спец. типами, т.е. абстрактным типом с единственной связанной процедурой-функцией, в некоторых случаях это даёт бОльшую гибкость - но только в тех, когда функция может иметь какое-то внутреннее состояние/описание (необходиомсть во внутренних полях, то бишь).

Автор:  Сергей Губанов [ Понедельник, 30 Июль, 2007 22:45 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

Не courier, а carrier.

Автор:  Илья Ермаков [ Понедельник, 30 Июль, 2007 23:22 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

Да, естественно... Заговорился :-) Плюс солнышко припекало.... :-)

Автор:  GameHunter [ Среда, 01 Август, 2007 22:44 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

Спасибо за совет. В самом деле, для моей задачи не связанные и, вообще, внешние
процедуры хороший вариант - как я сам до него не догадался?!

Автор:  GameHunter [ Суббота, 04 Август, 2007 09:35 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

В продолжение темы:

Я решил поиграться с возможностью расширения записей в стиле
Оберона-1 - т.е. явно вводя процедуры с параметром-записью
и ссылками на них. Для этого надо описывать примерно такие структуры:

Код:
TYPE
  Proc = PROCEDURE (VAR rec:Rec);
  Rec = RECORD
    p:Proc
  END;


Однако, XDS такую фразу не понимает: пишет в первом описании,
что Rec ему не знаком. Всё работает, если Proc определить как
PROCEDURE (rec:POINTER TO Rec), но в этом случае я переменные типа
Rec всегда буду вынужден размещать в динамической памяти - ведь
указатели разрешены только на объекты в куче.
Подскажите, пожалуйста, это ошибка, или так и должно быть?

Автор:  Илья Ермаков [ Суббота, 04 Август, 2007 11:27 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

А Вы попробуйте поставить в исходном тексте телегу (Rec) впереди лошади (PROCEDURE) - и всё получится. Просто процедурное поле - это указатель, а Оберон разрешает использование в описаниях указательных типов до их объявления. А вообще, в стиле Оберона, если память мне не изменяет, даже не объявлялся отдельный процедурный тип, а описывалось всё прямо по месту: RECORD proc: PROCEDURE (VAR rec:.. )...

Автор:  GameHunter [ Суббота, 04 Август, 2007 12:02 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

Пробовал я и так и сяк... Если в описании процедуры стоит VAR, то в XDS это не работает :(

Автор:  Илья Ермаков [ Суббота, 04 Август, 2007 12:44 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

Мда... Либо XDS не по стандарту...
Дома попробую посмотреть, сейчас XDS под рукой нету.
Или кто ещё из работавших с ним подскажет.

Автор:  Sergo [ Суббота, 04 Август, 2007 14:50 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

В XDS нормально компилируется такая конструкция:
Код:
   PRec = POINTER TO Rec;   
   Proc = PROCEDURE (VAR rec:Rec);
   Rec = RECORD p:Proc END;


Забавно, что в ETH Oberon исходный вариант, т.е.
Код:
TYPE
  Proc = PROCEDURE (VAR rec:Rec);
  Rec = RECORD p:Proc END;

компилируется без проблем. Oberon V4 (там язык - Oberon-1) переваривает только такой вариант
Код:
   PRec = POINTER TO Rec;   
   Proc = PROCEDURE (VAR rec: PRec);
   Rec = RECORD p:Proc END;

Автор:  Илья Ермаков [ Суббота, 04 Август, 2007 15:36 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

Просто в исходном Обероне обычно не выносился отдельный процедурный тип, а
описывался прямо по месту: RECORD Proc: PROCEDURE (a, b, c: INTEGER) END;
Такой вариант в XDS работает или нет? Если работает, то используйте его и не парьтесь - зачем ещё внешнее дообъявления процедурного типа? :-)

Автор:  Info21 [ Пятница, 17 Август, 2007 11:12 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

GameHunter писал(а):
Пробовал я и так и сяк... Если в описании процедуры стоит VAR, то в XDS это не работает :(


Как сам расчетчик, от души советую рассматривать XDS как основной вариант только в крайнем случае (типа если нужно срочно на линуксе).
За то, что он наоптимизирует, придется платить бОльшими усилиями программиста. Зачем тогда железо...

XDS станет действительно сильной опцией как тулзовина в контексте ББ...

Автор:  GameHunter [ Пятница, 17 Август, 2007 12:08 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

Не могли бы вы подробнее сформулировать свои претензии к XDS'у.

Автор:  Info21 [ Суббота, 18 Август, 2007 10:27 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

GameHunter писал(а):
Не могли бы вы подробнее сформулировать свои претензии к XDS'у.


0) среда разработки, что называется, "традиционная" -- обероновская (ББ) явно эффективнее (после переучивания, конечно).

1) конкретные глюки -- информация рассыпана по форумам, собирать нет возможности.

2) что-то с модулями/сбором мусора сделано тоже по-традиционному, а не по-обероновски.

3) (из личного опыта) оптимизирующий компилятор -- специализированная тулзовина с неизбежными подводными камнями (из-за сложности), поэтому применять таковой нужно только если невозможно иначе.

Автор:  Александр Ильин [ Суббота, 18 Август, 2007 16:17 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

info21 писал(а):
GameHunter писал(а):
Не могли бы вы подробнее сформулировать свои претензии к XDS'у.

1) конкретные глюки -- информация рассыпана по форумам, собирать нет возможности.

Из моего опыта: компилятор в некоторых случаях сваливается в бесконечную череду сообщений об ошибке, пока не переставишь местами модули в списке импорта. При этом, естественно, невозможно понять, что именно его не устраивает и как избежать этого в будущем. Перетасовать список импорта догадался случайно, благодаря тому, что использую Subversion.

info21 писал(а):
2) что-то с модулями/сбором мусора сделано тоже по-традиционному, а не по-обероновски.

Нет динамической загрузки, линкует только статически (exe либо dll).

info21 писал(а):
3) (из личного опыта) оптимизирующий компилятор -- специализированная тулзовина с неизбежными подводными камнями (из-за сложности), поэтому применять таковой нужно только если невозможно иначе.

Пока разобрался со всеми опицями компилятора и нашёл устраивающую меня комбинацию - не один день потерял.

А ещё мне не очень нравится, что у них INTEGER 16 бит, а 32 бита - это уже LONGINT. Это прошлый век.

Автор:  GameHunter [ Суббота, 18 Август, 2007 23:54 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

XDS, конечно, немного глючноватый, я уже заметил :(

Возможно, со временем я попристальнее пригляжусь к BlackBox'у.
Вероятно, я бы уже это сделал, если бы там имелись исключения
и многопоточность.

Ещё один вопрос, не по теме, но раз уж зашла речь...
Глюки - т.е. ошибки компилятора XDS, - которые меня
донимали, выражались в том, что программу нельзя
было скомпилировать. Согласно вашему опыту, существуют ли
такие ошибки компилятора, которые выражаются в не правильной
работе программы?

Автор:  Info21 [ Понедельник, 20 Август, 2007 09:51 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

GameHunter писал(а):
Согласно вашему опыту, существуют ли
такие ошибки компилятора, которые выражаются в не правильной
работе программы?


Лично мой опыт для этого явно недостаточен.
С другой стороны, практически любой оптимизирующий компилятор способен подставить подножку (особенно там, где требуют внимания ошибки округления -- из-за перестановки операций).

Автор:  Александр Ильин [ Понедельник, 20 Октябрь, 2008 09:49 ]
Заголовок сообщения:  Re: Процедурные типы в Обероне

GameHunter писал(а):
Согласно вашему опыту, существуют ли такие ошибки компилятора, которые выражаются в не правильной работе программы?
Ошибки кодогенерации есть, несколько раз натыкался. Вплоть до того, что изменение текстовой константы в тексте влияет на то, будет ли код нормально работать или внезапно вылетит трап на ровном месте. Иногда дурит с локальными переменными во вложенных процедурах. Обычно в таких случаях отключаем оптимизацию для всего модуля или выносим локальные процедуры наверх.

Страница 1 из 2 Часовой пояс: UTC + 3 часа
Powered by phpBB® Forum Software © phpBB Group
https://www.phpbb.com/