OberonCore
https://forum.oberoncore.ru/

Фундаментальность средств ООП в КП
https://forum.oberoncore.ru/viewtopic.php?f=8&t=2121
Страница 1 из 2

Автор:  Илья Ермаков [ Среда, 25 Ноябрь, 2009 22:47 ]
Заголовок сообщения:  Фундаментальность средств ООП в КП

Достаточно долгий период беспокоит меня данный вопрос.

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

Т.е. вопрос: сколько в них действительно "ядерного", а сколько - конкретно-исторически-сложившегося, что ещё должно быть перетрясено? (бесспорно, хорошо сложившегося, из опыта EthOS Шиперского и Оминк с ББ, но...).

Автор:  Александр Ильин [ Среда, 25 Ноябрь, 2009 23:20 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Связанные процедуры придают объектам больший "вес" в системе. Если вместо них используются процедурные переменные, то записи становятся просто данными, а процедуры - просто алгоритмами. Это более сбаллансированная система, но она требует больших усилий как для анализа структуры проекта, так и для рутинной работы с ним:
- obj.method(obj, ...); - дублирование "obj" при вызове метода;
- более длинная инициализация экземпляра при создании, поскольку все методы надо присвоить ему вручную;
- наследование метода выглядит слишком низкоуровнево: сохраняем копию процедуры, ставим свою процедуру, своя должна вызывать сохранённую копию;
- возможность во время выполнения изменять связанную процедуру не только затрудняет понимание структуры программы, но и делает невозможным наследование метода в общем случае без введения специальных механизмов и соглашений;
- есть возможность переопределить часть методов объекта во время исполнения, не создавая при этом нового типа. Я так понимаю, что это наносит серьёзный удар по одному из важных принципов ООП, согласно которому именно иерархия типов создаёт смысловой костяк программы, её понятийный аппарат.

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

Автор:  Илья Ермаков [ Среда, 25 Ноябрь, 2009 23:24 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Это понятно.

Мой вопрос нужно читать не с угла сравнения с Обероном (это уже считаем "проеханным"), а... ну, я написал же: можно ли признать эту группу средств КП устоявшимися (объективно, "научно"), или это ещё фаза поиска?

Автор:  Valery Solovey [ Среда, 25 Ноябрь, 2009 23:50 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Что-то я не понял вот этого момента.
Александр Ильин писал(а):
- наследование метода выглядит слишком низкоуровнево: сохраняем копию процедуры, ставим свою процедуру, своя должна вызывать сохранённую копию;
Можно по-подробнее?

Автор:  Александр Ильин [ Четверг, 26 Ноябрь, 2009 01:10 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Valery Solovey писал(а):
Можно по-подробнее?
Код:
TYPE
Object = POINTER TO ObjectDesc;
Method = PROCEDURE (obj: Object);
ObjectDesc* = RECORD
   do*: Method; (* overridable (="virtual") method *)
END;

NewObject = POINTER TO NewObjectDesc; (* this object can be in a different module *)
NewObjectDesc* = RECORD (ObjectDesc)
   inheritedDo: Method; (* a saved copy of ObjectDesc.do *)
END;

PROCEDURE DefaultMethod (obj: Object); (* can't be called directly if not exported from the base module *)
BEGIN
   (* do something *)
END DefaultMethod;

PROCEDURE Init* (obj: Object); (* initialize a new Object instance *)
BEGIN
   obj.do := DefaultMethod; (* assign the default method implementation *)
END Init;

(* the following procedures can be in a different module along with the NewObject itself *)

PROCEDURE NewMethod (obj: Object);
BEGIN
   obj(NewObject).inheritedDo(obj); (* <- call the inherited method *)
   (* do something else *)
END NewMethod;

PROCEDURE InitNewObject* (obj: NewObject);
BEGIN
   Init (obj); (* here obj.do will be initialized to the unpublished DefaultMethod *)
   obj.inheritedDo := obj.do; (* <- remember the inherited method *)
   obj.do := NewMethod; (* <- set our new method handler *)
END InitNewObject;
Для сравнения - аналогичный код на КП:
Код:
TYPE
Object* = POINTER TO EXTENSIBLE RECORD
END;

NewObject = POINTER TO RECORD (Object)
END;

PROCEDURE (obj: Object) Do* (), NEW;
BEGIN
   (* do something *)
END Do;

PROCEDURE (obj: NewObject) Do ();
BEGIN
   obj.Do^(); (* <- call the inherited method *)
   (* do something else *)
END Do;
Ни явных инициализаций, ни запоминания прежнего метода при наследовании. Автоматическое создание VMT супротив ручного.

Автор:  Александр Ильин [ Четверг, 26 Ноябрь, 2009 01:21 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Кстати, если я правильно понимаю, то подход с процедурными переменными-полями всегда будет работать быстрее таблиц виртуальных методов (VMT). Или нет?

Автор:  Илья Ермаков [ Четверг, 26 Ноябрь, 2009 02:20 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Ну, вроде бы, на одну косвенность меньше.

Автор:  Валерий Лаптев [ Четверг, 26 Ноябрь, 2009 09:40 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Да вводите просто: тип данных это есть множество значений + множество операций. Операции представляются в КП вот так. А чтобы обозначить, что эти операции для конкретного типа данных, вот вам параметр.

Мне подход КП нравится гораздо больше, чем в С++ и прочих. В КП ЯВНО задается параметр this, что снимает у начинающих МНОГИЕ неясности. Особенно непонятно - ЗАЧЕМ какой-то невидимый параметр, да еще указатель (с которыми большинство работает плохо).

Автор:  Peter Almazov [ Четверг, 26 Ноябрь, 2009 10:01 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Вот что я не понял при чтении описания языка, так это упоминание супер вызовов:
"It is recommended to minimize the use of procedure types and super calls, since they are considered obsolete." (выделение моё)
Насколько я понимаю, это и есть супер-вызов:
Александр Ильин писал(а):
obj.Do^(); (* <- call the inherited method *)
Если это так, за что они впали в такую немилость?

Автор:  Иван Кузьмицкий [ Четверг, 26 Ноябрь, 2009 10:29 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Я на FreePascal несколько раз влетал на трудновыловимые ошибки с супервызовами - банально забывал поставить вызов в нужном месте. Человеческий фактор, думаю, и есть основная причина немилости :)

Автор:  Александр Ильин [ Четверг, 26 Ноябрь, 2009 10:40 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Peter Almazov писал(а):
Насколько я понимаю, это и есть супер-вызов...Если это так, за что они впали в такую немилость?
Да, это именно он самый и есть.
А в немилость впал оттого, что композиция объектов предпочитается наследованию. Наследование достаточно допускать только на одну ступень: абстрактный объект и его реализация-наследник.
При необходимости наследование реализации легко делается через композицию.

Автор:  Александр Ильин [ Четверг, 26 Ноябрь, 2009 10:48 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Валерий Лаптев писал(а):
Мне подход КП нравится гораздо больше, чем в С++ и прочих. В КП ЯВНО задается параметр this, что снимает у начинающих МНОГИЕ неясности. Особенно непонятно - ЗАЧЕМ какой-то невидимый параметр, да еще указатель (с которыми большинство работает плохо).
Согласен! Сразу становится ясно, что такое метод на самом деле. Я долго не мог понять, что такое ООП из-за разных дельфийских наворотов. Например, в Дельфи внутри метода не только есть этот скрытый параметр Self (и вместе с ним особый тип procedure of object), но и все поля объекта находятся внутри метода в области прямой видимости, наравне с локальными переменными. Приходится вводить соглашения об именовании: префикс F для полей. Даже когда на 10й раз прочитаешь справку, всё равно остаётся впечатление, что там ещё может быть что-то скрытое, умолчательное. В Обероне всё сразу на виду, и по единообразным правилам.

Автор:  Info21 [ Четверг, 26 Ноябрь, 2009 10:51 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Иван Кузьмицкий писал(а):
банально забывал поставить вызов в нужном месте. Человеческий фактор, думаю, и есть основная причина немилости :)
Не совсем. Если человеческий фактор подскальзывается на банановой кожуре -- кто виноват? В принципе, под ноги же можно смотреть. Но и кожуру подмести тоже можно.

Автор:  Valery Solovey [ Четверг, 26 Ноябрь, 2009 10:53 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Александр Ильин писал(а):
А в немилость впал оттого, что композиция объектов предпочитается наследованию. Наследование достаточно допускать только на одну ступень: абстрактный объект и его реализация-наследник.
При необходимости наследование реализации легко делается через композицию.
Дело даже не в одной ступени, а в том, что некоторые ради возможности использовать ресурсы класса предпочитают наследование вместо объявления объекта. "Относледовался и используй себе".

Автор:  Иван Кузьмицкий [ Четверг, 26 Ноябрь, 2009 11:02 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Еще по поводу супер-вызовов. В документе "What's New in Component Pascal?" (Docu\CP-New.odc) написано:

Цитата:
Abstract methods may only be bound to abstract types, and they may not be called via super calls.


Ну а поскольку абстрактные методы используются довольно широко, то использование супер-вызовов не является "хорошим" стилем :)

Автор:  Валерий Лаптев [ Четверг, 26 Ноябрь, 2009 11:10 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Александр Ильин писал(а):
Peter Almazov писал(а):
Насколько я понимаю, это и есть супер-вызов...Если это так, за что они впали в такую немилость?
Да, это именно он самый и есть.
А в немилость впал оттого, что композиция объектов предпочитается наследованию. Наследование достаточно допускать только на одну ступень: абстрактный объект и его реализация-наследник.
При необходимости наследование реализации легко делается через композицию.

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

Автор:  Сергей Губанов [ Четверг, 26 Ноябрь, 2009 12:20 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Супервызовы весьма удобны при реализации сериализации/десериализации.

Автор:  Galkov [ Четверг, 26 Ноябрь, 2009 14:54 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Александр Ильин писал(а):
Например, в Дельфи внутри метода не только есть этот скрытый параметр Self (и вместе с ним особый тип procedure of object)

Про procedure of object
Это не какой-то особый тип из серии рюшечек, а очень хорошая и нужная вещь.
Два dword-а, один из которых есть адрес объекта, а второй адрес его метода (хотя порядок кажется обратный).
Смысл в том, что если разделить их по отдельности, то такие яйца получатся - мама не горюй.
Вот в C++ есть тип "метод класса", отделенный от объекта (а методы-то разные бывают, и виртуальные в т.ч.).
Вот там и происходит это "мама не горюй". НИЗЯ, оказывается, на языке, позиционирующем себя как специально созданный для создания пользовательских типов, воспроизвести этот тип, простой как топор.

А когда все это в одном типе - стыковка типа объекта и его метода производится на уровне компиляции, в тот момент, когда такой переменной делается присваивание. Все же действительно просто как топор становится.
Вот поэтому в QT появляется кобинация слотов/сигналов, а в додиезе - делегаты.
Никак пока в толк не возьму, отчего в КП нет такого полезного типа :(

P.S. Это ничего, что я в терминах "атомно-молекулярной теории" изъяснялся ??? :)

Автор:  Евгений Темиргалеев [ Четверг, 26 Ноябрь, 2009 15:16 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Galkov писал(а):
Никак пока в толк не возьму, отчего в КП нет такого полезного типа
В КП есть метаинформация. По-моему это оно самое.

Автор:  Сергей Губанов [ Четверг, 26 Ноябрь, 2009 15:33 ]
Заголовок сообщения:  Re: Фундаментальность средств ООП в КП

Galkov писал(а):
Никак пока в толк не возьму, отчего в КП нет такого полезного типа :(
Потому что выгоды от него в КП кот наплакал, так как в КП "сообщения рулят", а в языках со сборщиком мусора он ещё и неявным якорем объекта будет. Что касается дотнета, то там делегаты -- это самостоятельные объекты, со всеми вытекающими последствиями лишней нагрузки на сборщик мусора на каждый чих.

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