OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Воскресенье, 28 Апрель, 2024 00:04

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




Начать новую тему Ответить на тему  [ Сообщений: 31 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Процедурные типы
СообщениеДобавлено: Суббота, 05 Ноябрь, 2022 10:31 

Зарегистрирован: Воскресенье, 06 Август, 2017 19:33
Сообщения: 80
Расскажите, что такое процедурные типы, как ими пользоваться (примеры), что они дают, зачем нужны и можно ли обойтись без них.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Суббота, 05 Ноябрь, 2022 23:59 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
Если Вас интересует именно Компонентный Паскаль, то считайте, что их и нет.
Цитата:
Рекомендуется минимизировать использование процедурных типов и супер-вызовов [super calls], т.к. они считаются устаревшими средствами. Они пока сохранены, чтобы облегчить использование существующих программ на Обероне-2. Поддержка этих средств может быть уменьшена в последующих выпусках продукта.

Используйте записи с методами(связанными процедурами).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Понедельник, 07 Ноябрь, 2022 13:35 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 660
Цитата:
Variables of a procedure type T have a procedure (or NIL) as value. If a procedure P is assigned to a variable of type T, the formal parameter lists (see Ch. 10.1) of P and T must match (see App. A). P must not be a predeclared procedure or a method nor may it be local to another procedure.

Код:
   ProcedureType = PROCEDURE [FormalParameters].



Часто в обычных апи процедурные переменные используются как функции обратного вызова (коллбэки):
Код:
TYPE Action = PROCEDURE (element: Element);

PROCEDURE Iterate (list: ElementList; action: Action);
  VAR e: Element; ind: INTEGER;
BEGIN
  ASSERT(action # NIL, 20);
  ...
  e := ...; ind := ...;
  action(e);
END Iterate;

PROCEDURE Do (e: Element); BEGIN ... END Do;

PROCEDURE P;
  VAR proc: Action;
BEGIN
  proc := Do; ...  (* процедуры, кстати, могут присваиваться переменным, при условии совпадения типов *)
  Iterate(list, Do)
END P;

Также часто нужно, чтобы Action имела больше параметров, определяемых задачей, чем известно процедуре Iterate. Например, Action должна окрасить элементы в заданный цвет color. Как передать этот параметр, так чтобы не менять Iterate? Вероятно, нужно добавить некий универсальный параметр процедуре Action, который тж передается Iterate, которая, в свою очередь, передает его в Action. Этот универсальный параметр в прочих ЯВУ/библиотеках обычно трактуется как адрес чего-то в памяти, что неизвестно процедуре Iterate, и что будет истолковано процедурой Action. В КП, к счастью, нет адресов и памяти, а есть универсальный (т.е. всеобъемлющий) тип ANYREC/ANYPTR, который можно уточнить (расширить):

TYPE Action = PROCEDURE (element: Element; VAR par: ANYREC);
Par = RECORD col: INTEGER END;

PROCEDURE Do (e: Element; VAR par: ANYREC);
VAR c: INTEGER;
BEGIN
WITH par: Par DO e.color := par.col ELSE HALT(20) END;
END Do;

PROCEDURE Iterate (list: ElementList; do: Action; VAR par: ANYREC);
BEGIN
... do (e, par) ...
END Itetate;

Таким образом процедуре Action можно передать произвольное количество произвольных параметров - как поля записи Par.

Однако КП дает возможность решить такую задачу еще элегантнее (ИМХО), явно указав на связь Action и Par:

Код:
TYPE
  Par = RECORD col: INTEGER END;

PROCEDURE (VAR par: Par) Do (e: Element), NEW;
BEGIN
  e.color := par.col
END Do;

PROCEDURE Iterate (list: ElementList; VAR par: Par);
BEGIN
  ... par.Do(e)
END Iterate;


Еще бОльшее преимущество - когда действия с элементом списка нужно предусмотреть разные, и параметризуемые по-разному:

Код:
TYPE
  Action = ABSTRACT RECORD END;
  A1 = RECORD (Action) col: INTEGER END;
  A2 = RECORD (Action) s: String; pos: INTEGER END;

PROCEDURE (VAR a: Action) Do (e: Element), NEW, ABSTRACT;
PROCEDURE (VAR a: A1) Do (e: Element); BEGIN ... END Do;
PROCEDURE (VAR a: A2) Do (e: Element); BEGIN ... END Do;

PROCEDURE P;
  VAR a1: A1; a2: A2;
BEGIN
  a1.col := ...; Iterate(list, a1);
  a2.s := '...'; a2.pos := ...; Iterate(list, a2)
END P;


Отмечу, что "между строк": КП на i386 в приведенном примере совершенно не использует динамическую память: a1 a2 создаются в автоматической памяти (в стеке), стоимость их размещения и освобождения ~0.

Тем не менее, мне не до конца ясно, почему рекомендуется минимизировать использование процедурных типов, как процитировал ComDiv. Это средство языка менее выразительное, но, кажется, вполне безопасное.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Понедельник, 07 Ноябрь, 2022 18:19 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 521
Откуда: Украина, Днепропетровская обл.
adimetrius писал(а):
Тем не менее, мне не до конца ясно, почему рекомендуется минимизировать использование процедурных типов, как процитировал ComDiv. Это средство языка менее выразительное, но, кажется, вполне безопасное.
Там вроде бы OMinc опасались, что если где-то в модуле N есть процедурная переменная со ссылкой на процедуру из модуля M, и модуль M выгружают, то эта переменная может потом указывать в никуда. То ли есть проблемы с определением такой ситуации для безопасной выгрузки.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Понедельник, 07 Ноябрь, 2022 18:47 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
Процедурные типы - это, банально, избыточное средство при наличии связанных процедур. При этом в сравнении с ними оно более низкоуровневое и это единственное средство, опирающееся на структурную, а не именную совместимость по типам. Чистое наследие для большей совместимости. Если же рассматривать язык исключительно с чистого листа, то никакой необходимости в процедурных типах в Компонентном Паскале нет.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Понедельник, 07 Ноябрь, 2022 20:19 
Администратор

Зарегистрирован: Вторник, 15 Ноябрь, 2005 01:14
Сообщения: 4695
Откуда: Россия, Орёл
Ранее процедурные типы были помечены в Сообщении о языке к последующему удалению. Когда Оминки прекратили разработку ББ, сообщество это дело (такие изменения в языке) приморозило.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Понедельник, 07 Ноябрь, 2022 20:45 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 660
Oleg N. Cher писал(а):
adimetrius писал(а):
Тем не менее, мне не до конца ясно, почему рекомендуется минимизировать использование процедурных типов, как процитировал ComDiv. Это средство языка менее выразительное, но, кажется, вполне безопасное.
Там вроде бы OMinc опасались, что если где-то в модуле N есть процедурная переменная со ссылкой на процедуру из модуля M, и модуль M выгружают, то эта переменная может потом указывать в никуда. То ли есть проблемы с определением такой ситуации для безопасной выгрузки.


При выгрузке модулей та же проблема вообще с любыми указателями: выгрузили М, а переменная п: М.Т осталась, и попытки вызвать связанные с М.Т процедуры - тоже в никуда. И в текущей реализации (в линукс) последствия непредсказуемы, т.к. платформенная защита памяти от исполнения не используется. Но, как я понимаю идеологию ББ: выгрузка модулей - действие этапа разработки, в "боевой системе" этого делать не следует; поэтому соответствующие защиты не реализованы.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Понедельник, 07 Ноябрь, 2022 20:49 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 660
Comdiv писал(а):
Процедурные типы - это, банально, избыточное средство при наличии связанных процедур. При этом в сравнении с ними оно более низкоуровневое и это единственное средство, опирающееся на структурную, а не именную совместимость по типам. Чистое наследие для большей совместимости. Если же рассматривать язык исключительно с чистого листа, то никакой необходимости в процедурных типах в Компонентном Паскале нет.


Очень интересным для себя нахожу замечание про структурную, а не именную совместимость типов!

Любопытно, а как реализовать StdInterpreter без процедурных типов? Т.е. возможность вызывать команды из текста?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Вторник, 08 Ноябрь, 2022 02:38 
Аватара пользователя

Зарегистрирован: Вторник, 28 Август, 2007 00:55
Сообщения: 521
Откуда: Украина, Днепропетровская обл.
А мне любопытно: как реализовать коллбэки без процедурной переменной, чисто на связанных с типом процедурах?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Вторник, 08 Ноябрь, 2022 12:28 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Считаю, что намерение Оминк исключить процедурные переменные было опрометчивым.
Некая эйфория от мейнстрим-модели ООП.

Много ценных паттернов в стиле классического Оберона и "ООП вручную" реализуется хорошо как раз на процедурных переменных.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Вторник, 08 Ноябрь, 2022 13:28 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 660
Oleg N. Cher писал(а):
А мне любопытно: как реализовать коллбэки без процедурной переменной, чисто на связанных с типом процедурах?


Если бы только для колбэков были нужны процедурные типы, то место им было бы - в SYSTEM. Но можно ли систему Оберон сделать без процедурных типов - интересно в плане необходимости и достаточности этого средства в языке.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Вторник, 08 Ноябрь, 2022 14:52 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
adimetrius писал(а):
Любопытно, а как реализовать StdInterpreter без процедурных типов? Т.е. возможность вызывать команды из текста?
Если речь о получении через мета-информацию процедурной переменной для её вызова, то разве нельзя заменить возврат процедурной переменной на возврат записи с процедурой?

adimetrius писал(а):
Если бы только для колбэков были нужны процедурные типы, то место им было бы - в SYSTEM. Но можно ли систему Оберон сделать без процедурных типов - интересно в плане необходимости и достаточности этого средства в языке.
Вы правильно подмечаете про SYSTEM, тем более, что в общем случае аргументы из исходного языка могут не отображаться напрямую в КП. Но с замкнутой на себе системе всё ещё проще.
Было:
Код:
MODULE IndirectCall;

TYPE Proc*= PROCEDURE(i: INTEGER);

VAR proc: Proc;

PROCEDURE Install*(p: Proc);
BEGIN   proc := p
END Install;

PROCEDURE Go*;
BEGIN   proc(2)
END Go;

END IndirectCall.

Стало:
Код:
MODULE IndirectCall;

TYPE Proc*= POINTER TO ABSTRACT RECORD END;

VAR proc: Proc;

PROCEDURE (p: Proc) Do*(i: INTEGER), NEW, ABSTRACT;

PROCEDURE Install*(p: Proc);
BEGIN   proc := p
END Install;

PROCEDURE Go*;
BEGIN   proc.Do(2)
END Go;

END IndirectCall.

Нужны примеры, где этого не хватает. А так - есть несколько трансляторов Oberon в Java, а там нет никаких процедурных переменных.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Вторник, 08 Ноябрь, 2022 20:42 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 588
Откуда: Москва
Илья Ермаков писал(а):
Считаю, что намерение Оминк исключить процедурные переменные было опрометчивым.
Некая эйфория от мейнстрим-модели ООП.

Много ценных паттернов в стиле классического Оберона и "ООП вручную" реализуется хорошо как раз на процедурных переменных.

Именно так


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Среда, 09 Ноябрь, 2022 17:11 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
adimetrius писал(а):
Любопытно, а как реализовать StdInterpreter без процедурных типов? Т.е. возможность вызывать команды из текста?
Посмотрел код StdInterpreter
Код:
Meta.Lookup(mod, i);
IF i.obj = Meta.modObj THEN
   i.Lookup(proc, i);
   IF i.obj = Meta.procObj THEN
      i.GetReturnType(t);
      IF (t.typ = 0) & (i.NumParam() = numPar) THEN
         i.ParamCallVal(par, t, ok)
Посмотрел Meta
Код:
IF proc.obj = procObj THEN adr := proc.adr
ELSE ASSERT((proc.obj = varObj) & (proc.typ = procTyp), 22);
   SYSTEM.GET(proc.adr, adr);
...
ret := Kernel.Call(adr, sig, data, n);
Kernel
Код:
CALL(adr);
PROCEDURE [code] CALL (a: INTEGER) 0FFH, 0D0H;   (* call AX *)

Я что-то неправильно понял, или никаких процедурных типов там и не было, то есть, сам BlackBox отвечает на заданный вопрос?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Среда, 09 Ноябрь, 2022 17:18 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
Дмитрий Дагаев писал(а):
Илья Ермаков писал(а):
Считаю, что намерение Оминк исключить процедурные переменные было опрометчивым.Некая эйфория от мейнстрим-модели ООП. Много ценных паттернов в стиле классического Оберона и "ООП вручную" реализуется хорошо как раз на процедурных переменных.
Именно так
Коллеги, можете подробней осветить свою точку зрения? Отсутствие процедурных типов вас не устраивало бы из-за производительности или из-за архитектурных особенностей?


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Среда, 09 Ноябрь, 2022 20:52 

Зарегистрирован: Вторник, 01 Март, 2011 09:34
Сообщения: 588
Откуда: Москва
Comdiv писал(а):
Дмитрий Дагаев писал(а):
Илья Ермаков писал(а):
Считаю, что намерение Оминк исключить процедурные переменные было опрометчивым.Некая эйфория от мейнстрим-модели ООП. Много ценных паттернов в стиле классического Оберона и "ООП вручную" реализуется хорошо как раз на процедурных переменных.
Именно так
Коллеги, можете подробней осветить свою точку зрения? Отсутствие процедурных типов вас не устраивало бы из-за производительности или из-за архитектурных особенностей?

1. Дело в мейнстрим-модели ООП.
2. Я 27-го на дне Оберона подробнее выскажусь на эту тему.
3. Считаю правильным использовать RESTRICT, а не вставлять/выкидывать из компилятора существенные функции, в зависимости от конкретной прикладной задачи.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Среда, 09 Ноябрь, 2022 22:01 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
Дмитрий Дагаев писал(а):
1. Дело в мейнстрим-модели ООП.
Вопрос неудачного выбора ООП в КП я бы в этой теме не рассматривал. Вопрос о процедурных типах при наличии даже самой из удачных моделей ООП. Или это о принципиальном отказе от всех, кроме модели первоначального Oberon?

Цитата:
2. Я 27-го на дне Оберона подробнее выскажусь на эту тему.
Жаль :). Было бы здорово, если бы все рассказывали об интересующих темах по мере поступления, а не подстраивались под графики выступлений. Будем ждать, но, надеюсь, хотя бы Илья прояснит раньше.

Цитата:
3. Считаю правильным использовать RESTRICT, а не вставлять/выкидывать из компилятора существенные функции, в зависимости от конкретной прикладной задачи.
То есть, путь Паскаль->Модула-2->Оберон Вам не подходит?
Как мне кажется, ООП в КП покрывает прикладные задачи, которые решают процедурные типы. Как раз интересно прояснить ту часть, в которой они могут выходить за рамки.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Пятница, 11 Ноябрь, 2022 15:44 
Аватара пользователя

Зарегистрирован: Суббота, 16 Февраль, 2008 02:47
Сообщения: 660
Да, согласен, для вызова команд-процедур через Dialog.Call/StdInterpreter нет нужды иметь процедурные переменные в языке.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Воскресенье, 13 Ноябрь, 2022 14:02 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
Comdiv писал(а):
Процедурные типы - это единственное средство, опирающееся на структурную, а не именную совместимость по типам.
Не совсем точно, потому что в Oberon структурная совместимость также у открытых массивов, допустимых в формальных параметрах, а в Компонентном Паскале и для указателей:
Цитата:
Правила совместимости для указателей были ослаблены и упрощены. Теперь указатели совместимы по структуре; то есть два указательных типа, имеющих общий базовый тип, являются совместимыми. Это может быть полезно в основном в сигнатурах процедур, где раньше было невозможно использовать функции, подобные следующей:

PROCEDURE P (p: POINTER TO ARRAY OF INTEGER)


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Процедурные типы
СообщениеДобавлено: Понедельник, 14 Ноябрь, 2022 14:23 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1449
Откуда: Киев
adimetrius писал(а):
При выгрузке модулей та же проблема вообще с любыми указателями: выгрузили М, а переменная п: М.Т осталась, и попытки вызвать связанные с М.Т процедуры - тоже в никуда. И в текущей реализации (в линукс) последствия непредсказуемы, т.к. платформенная защита памяти от исполнения не используется. Но, как я понимаю идеологию ББ: выгрузка модулей - действие этапа разработки, в "боевой системе" этого делать не следует; поэтому соответствующие защиты не реализованы.
Тут, видимо, дело в трактовке процедурного типа - если его воплощать максимально прямо, а не как более сложный неявный объект, то переменная процедурного типа будет просто указателем на код без привязки к модулю с возможностью вызова непонятно чего. У объекта же потенциально больше возможностей по предотвращению обращения куда попало, пусть и с последствиями для кода, который пытается это делать.


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

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


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

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


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

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