OberonCore
https://forum.oberoncore.ru/

Делегаты vs процедурные типы
https://forum.oberoncore.ru/viewtopic.php?f=86&t=3549
Страница 1 из 1

Автор:  Info21 [ Воскресенье, 21 Август, 2011 12:35 ]
Заголовок сообщения:  Делегаты vs процедурные типы

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

Что-то на эту тему похоронено в этой ветке: viewtopic.php?f=29&t=2125
хотелось бы просто выделить отдельно и ясно.

(Делегат = безопасный указатель на функцию, см. http://ru.wikipedia.org/wiki/%D0%94%D0% ... 0%B8%D0%B5))

Автор:  Илья Ермаков [ Воскресенье, 21 Август, 2011 19:34 ]
Заголовок сообщения:  Re: Делегаты vs процедурные типы

Основное отличие по сравнению с PROCEDURE в КП - это возможность указать не только на процедуру, но и на метод конкретного объекта.

Т.е. если есть VAR do: DELEGATE (a, b, c: INTEGER); obj: SomeObject,
и у типа SomeObject есть связанная процедура (obj: SomeObject) Do (a, b, c: INTEGER),
то мы можем:

do := obj.Do;
...
а потом косвенно вызвать метод Do объекта obj:
do(a, b, c).

Делегат хранит пару (объект, указатель на процедуру), где объект в частном случае может быть не определён (для простых процедур).

Моё мнение:
1) Концептуально штука простая и естественная. Если есть указатель на процедуру, то какая разница, кто обработает вызов - модуль или объект. На это всегда народ в спорах и упирает.
2) В реализации есть некоторые нюансы, но не особенные...
3) По значению своему не столь важно, чтобы разводить из мухи слона (как некоторые делали), но при массовых нововведениях в язык, когда-нибудь (например, при добавлении ЦД), я бы ввёл. Синтаксически просто сделал бы для всех PROCEDURE-переменных возможность указывать как на процедуры, так и на объект.метод. Похерив системную совместимость, пусть для системных указателей на процедуры на других языках будет флаг в SYSTEM.

===

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

Автор:  Пётр Кушнир [ Воскресенье, 21 Август, 2011 19:47 ]
Заголовок сообщения:  Re: Делегаты vs процедурные типы

в GPCP для jvm процедурные типы вообще отменили.

Автор:  Илья Ермаков [ Воскресенье, 21 Август, 2011 20:37 ]
Заголовок сообщения:  Re: Делегаты vs процедурные типы

Да, после тех дебатов я писал примеры в Вики, как имитировать делегаты:
http://oberoncore.ru/wiki/blackbox/ex/delegates

Автор:  Info21 [ Понедельник, 22 Август, 2011 08:35 ]
Заголовок сообщения:  Re: Делегаты vs процедурные типы

В общем, синтаксический сахар, уменьшающий прозрачность реализации.

Автор:  Сергей Губанов [ Понедельник, 22 Август, 2011 11:26 ]
Заголовок сообщения:  Re: Делегаты vs процедурные типы: делегат в C#

Делегат это не указатель на функцию, а это объект динамически размещаемый в куче и лишний раз почём зря напрягающий своей тушкой сборщик мусора. Внутри тушки делегатного объекта лежит указатель на таргетный объект "делегировавший" его и особым образом закодирована информация о методе таргетного объекта, который через этот делегат можно вызвать. Особым образом закодирована означает, что там не обязательно адрес начала кода процедуры ибо ежели процедуру ни разу не вызвали, то и машинный код для неё не генерировался (в дотнете JIT компиляция). И лишь только благодаря синтаксическому сахару языка C# делегат в исходном тексте программы может выглядеть (а может и не выглядеть) как "указатель на функцию". Однако это не мешает работать с ним (в случае необходимости) как с обыкновенным дотнетным объектом. Как у обычного объекта у него есть методы:
* получения таргетного объекта,
* получения объекта метаинформации о процедуре,
* и конечно все стандартные методы отнаследованные от базового System.Object.
Естественно он является GC-якорем для таргетного объекта. Ну ещё с помощью них можно мультикаст делать (ещё одна сладкая плюшка для ленивых) и вызывать в отдельном потоке взятом из пула потоков.

Делегаты применяются теми кому лень писать "много" исходного текста, а оверхед по памяти/скорости их не волнует, то есть когда приоритет отдаётся скорости написания исходного текста программы в ущерб её производительности.

Автор:  Сергей Губанов [ Понедельник, 22 Август, 2011 11:41 ]
Заголовок сообщения:  Re: Делегаты vs процедурные типы

Илья Ермаков писал(а):
Да, после тех дебатов я писал примеры в Вики, как имитировать делегаты:
http://oberoncore.ru/wiki/blackbox/ex/delegates
Не эффективно. Делегаты можно реализовать так, что они не будут каждый раз размещаться в динамической памяти и напрягать сборщик мусора своими тушками. Уберите из описаний
Код:
   TYPE
      PlayHandler = POINTER TO RECORD (Buttons.Handler) pl: Player END;
      StopHandler = POINTER TO RECORD (Buttons.Handler) pl: Player END;
таргетный объект pl: Player и тогда объекты ссылочных типов PlayHandler и StopHandler можно будет сделать синглетонами и разместить в памяти лишь однажды. Таргетный объект правда каждый раз придётся подсовывать им отдельно, выглядеть будет не красиво, но зато без оверхеда по памяти на делегатную тушку.

Автор:  Info21 [ Понедельник, 22 Август, 2011 14:04 ]
Заголовок сообщения:  Re: Делегаты vs процедурные типы: делегат в C#

Сергей Губанов писал(а):
то есть когда приоритет отдаётся скорости написания исходного текста программы в ущерб её производительности.
А также в ущерб ясности реализации и, соответственно, главному качеству хорошей программы -- evolvability.

Автор:  Илья Ермаков [ Понедельник, 22 Август, 2011 17:19 ]
Заголовок сообщения:  Re: Делегаты vs процедурные типы: делегат в C#

Сергей Губанов писал(а):
Делегат это не указатель на функцию, а это объект динамически размещаемый в куче и лишний раз почём зря напрягающий своей тушкой сборщик мусора. Внутри тушки делегатного объекта лежит указатель на таргетный объект "делегировавший" его и особым образом закодирована информация о методе таргетного объекта, который через этот делегат можно вызвать.


Ну, в Шарпе его сделали объектом, но это совершенно не обязательно.
Никто не мешает сделать value-значением. Просто копировать пару (адрес процедуры, указатель на объект).
Это справедливости ради.

(Так, в тему: мне были как-то интенсивно (по всей подсистеме) нужны указатели на процедуры, устойчивые к выгрузке модулей. А подсистема серверная, т.е. постоянно по имени раскапывать через Meta не будешь. Завёл тип RECORD с указателем на Kernel.Module и со смещением точки входа в процедуру от начала модуля. При разыменовании (procPtr.GetProc) проверяется, что модуль не выгружен (mod.refcnt >= 0), а если выгружен, то ищется его новая версия, выясняется имя процедуры по старой версии - и обновляется.)

Автор:  Илья Ермаков [ Понедельник, 22 Август, 2011 17:20 ]
Заголовок сообщения:  Re: Делегаты vs процедурные типы

Сергей Губанов писал(а):
Уберите из описаний [code] TYPE
PlayHandler = POINTER TO RECORD (Buttons.Handler) pl: Player END;
StopHandler = POINTER TO RECORD (Buttons.Handler) pl: Player END;


А Вы досмотрите статью до конца. Там в конце выведен окончательный вариант без "тушек".

Автор:  Сергей Губанов [ Понедельник, 22 Август, 2011 19:18 ]
Заголовок сообщения:  Re: Делегаты vs процедурные типы: делегат в C#

Илья Ермаков писал(а):
Ну, в Шарпе его сделали объектом, но это совершенно не обязательно.
Никто не мешает сделать value-значением.
Должна быть виртуальная процедура. Для её вызова нужен указатель. Вот указатель на синглетон внуть структуры запихать можно. Это я про дотнет. А в Оберонах, да можно.

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