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 таргетный объект pl: Player и тогда объекты ссылочных типов PlayHandler и StopHandler можно будет сделать синглетонами и разместить в памяти лишь однажды. Таргетный объект правда каждый раз придётся подсовывать им отдельно, выглядеть будет не красиво, но зато без оверхеда по памяти на делегатную тушку.
PlayHandler = POINTER TO RECORD (Buttons.Handler) pl: Player END; StopHandler = POINTER TO RECORD (Buttons.Handler) pl: Player END; |
Автор: | 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/ |