OberonCore https://forum.oberoncore.ru/ |
|
Нужны ли Оберону конструкторы, деструкторы и исключения? https://forum.oberoncore.ru/viewtopic.php?f=29&t=1206 |
Страница 6 из 9 |
Автор: | Александр Ильин [ Четверг, 23 Октябрь, 2008 07:17 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Я считаю, что из троицы конструкторы-деструкторы-исключения Оберону нужны прежде всего конструкторы. Компонентному Паскалю конструкторы не нужны в связи с наличием ABSTRACT'ных записей. Деструкторы в виде FINALIZE есть везде, а при желании вызывать их вручную это элементарно реализуется дополнительным методом. Есть, правда, неопределённость со стековыми записями: для них нельзя гарантированно назначить ни конструкторов, ни деструкторов. Возможно, я чего-то тут не знаю. Другой вопрос - это возникновение исключения, при котором финализация может быть отложена на неопределённый срок. Однако, следует чётко понимать, что исключение - это не правило. Если возник фатальный сбой, то освобождение ресурсов может подождать. |
Автор: | ain [ Четверг, 23 Октябрь, 2008 07:22 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Иван Кузьмицкий писал(а): Обработка исключений придумана для того, чтобы подавить аварийную ситуацию и, по возможности, вернуть вычисление в рабочее русло. А вот если проблема вылезет в секции finally, то уже никакие примочки не помогут. Так что лучше придавать себе уверенности жёсткими проверками пред- и постусловий, нежели обёртывать всё и вся в try...except. Лучше, если ошибка проявит себя как можно раньше, а не будет задавлена обработчиком исключения. Для того и существует секция finally, чтобы сделать финальные действия, которые нужно сделать в любом случае. Естественно, никакие обрадотки тут не ведуться, практически – закрытие файлов, освобождение памяти и тому подобное. А вы, зачем-то притащили сюда в try...except. Я об этой паре ни слова не сказал. И скажу честно, у меня в моих программах нет ни одной секции except. Вообще. А вот try... finally – много. И именно потому, что проверки я прописываю, но вот всех ситуаций не предусмотришь. Особенно ситуации, которые возникают не в программе, а за её пределами, в операционке – может кто память пожрал или иные ресурсы кончились. Иван Кузьмицкий писал(а): Отработка подавления аварийной ситуации тоже может содержать ошибку, которая как раз вылезет в самый интересный момент Может, если использовать не по назначению. Евгений Темиргалеев писал(а): А экскепшен может произойти в любой момент - типа той же нехватки памяти - в том месте, где вы финалли не предусмотрели. Или было лень написать. Или забыли про какой-то ресурс. В КП память собирает сборщик мусора (100% гарантия сборки, программист ничего не пишет для этого); прочие ресурсы типа файлов закрываются в FINALIZE (программист реализует метод; вызовов не пишет; гарантия освобождения 100%). Я вызвал процедуру. В ней локальная переменная типа TQuery. Мне нужно сделать запрос к базе и т.д. В итоге, я обращаюсь к внешнему ресурсу – к операционной системе, для получения ресурса. Получил, тут бац и что-то меня выбросило. В секции finally я спокойно освободил внешние ресурсы и вышел из процедуры. Кстати, проверить, вышел я аварийно или нет тоже не вопрос, если это важно для вызывающего процесса. |
Автор: | Edward Ivanov [ Четверг, 23 Октябрь, 2008 08:32 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
В Обероне ошибки внутри программных модулей легко локализуются и пропалываются. При условии, что варится внутренняя кухня без обращения к внешней среде. В этом случае можно обойтись одними Asserta'ми. В случае же взаимодействия со внешней средой - все сложнее, тут действует правило - "лучше перебдеть, чем недобдеть" - лучше предупредить юзера о внештатной ситуации, а не поставить его перед свершившимся фактом. К примеру, вызываю COM-объект, а его нет - юзер прибил dll. Есть случаи, когда задача крутиться в цикле, и её нежелательно останавливать из-за возникшего трапа, лучше подавить с выдачей в лог или предупреждением. |
Автор: | Edward Ivanov [ Четверг, 23 Октябрь, 2008 08:41 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Если мне приспичится написать на ББ приложение средствами WinAPI - то я буду практически беззащитен. Оно мне надо? |
Автор: | AVC [ Четверг, 23 Октябрь, 2008 08:53 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Александр Ильин писал(а): Компонентному Паскалю конструкторы не нужны в связи с наличием ABSTRACT'ных записей. Я пока не понял этот аргумент.В Си++ тоже есть абстрактные классы (классы с чисто виртуальными функциями нельзя инстанцировать), однако потребность в конструкторах это не отменяет. Вероятно, Вы имеете в виду, что в таком случае конструктор можно заменить фабричной функцией. (Что, кстати, можно приравнять к виртуальному конструктору. Это бонус.) Но фабричная функция в КП имеет один недостаток: новый объект может быть создан только в динамической памяти. Но ведь Оберон/КП не Java? Александр Ильин писал(а): Есть, правда, неопределённость со стековыми записями: для них нельзя гарантированно назначить ни конструкторов, ни деструкторов. Возможно, я чего-то тут не знаю. Смутно вспоминаю некоторые расширения в Object Oberon.Интересно, нельзя ли расширить язык подобной конструкцией? Код: RECORD IMHO, синтаксически это вполне в духе языка, новых ключевых слов не надо.n: INTEGER; f: Files.File; BEGIN n := 0; (* инициализировать f необязательно, т.к. указатели и так инициализируются NIL *) CLOSE IF (f # NIL) & f.isOpen() THEN f.Close END END; Главная мысль: обеспечить гарантированную минимальную инициализацию (т.е. это не совсем конструктор, т.к. без параметров), а также финализацию объектов не только в динамической памяти. |
Автор: | AVC [ Четверг, 23 Октябрь, 2008 09:18 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Другой вариант: расширить синтакс процедуры. Код: PROCEDURE TramPamPam; Этот вариант может оказаться more convenient, т.к. не порождает вопросы с наследованием, которые могли бы возникнуть применительно к записям-классам.VAR f: Files.File; BEGIN ... CLOSE (* аналог finally *) IF (f # NIL) & f.isOpen() THEN f.Close END END TramPamPam; Обращаю внимание на сугубую опциональность секции CLOSE. Её имеет смысл использовать только для освобождения управляемых ресурсов (вроде файлов и т.п.). Проблем с освобождением памяти (как в Си++) в Обероне нет. |
Автор: | Trurl [ Четверг, 23 Октябрь, 2008 09:43 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Александр Ильин писал(а): Kernel.Try и Kernel.TrapHandler - пожалуйста. Аналогичным образом можно реализовать любую работу с исключениями внутри BlackBox - библиотечными средствами. Тема, я так понимаю, о том, надо ли это всё в языке. Я по-прежнему считаю, что нет. Проблема в том, что Код: TryHandler* = PROCEDURE (a, b, c: INTEGER); PROCEDURE Try* (h: TryHandler; a, b, c: INTEGER); и чтобы обрабатывать исключения в процедуре, её надо приводить к виду Код: PROCEDURE MyProc(a, b, c: INTEGER); Возможно в языке нужны другие средства, которые бы позволили сделать удобные библиотечные средства. |
Автор: | Александр Ильин [ Четверг, 23 Октябрь, 2008 10:03 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
AVC писал(а): Александр Ильин писал(а): Компонентному Паскалю конструкторы не нужны в связи с наличием ABSTRACT'ных записей. Я пока не понял этот аргумент... Вероятно, Вы имеете в виду, что в таком случае конструктор можно заменить фабричной функцией.AVC писал(а): Но фабричная функция в КП имеет один недостаток: новый объект может быть создан только в динамической памяти. Но ведь Оберон/КП не Java? Мне представляется, что стековые объекты имеют ограниченный срок жизни и сферу применения, и в этой связи не нуждаются в дополнительной автоматике. Если нужна инициализация-финализация - пользуйтесь динамической памятью (на то сборка мусора и нужна, чтобы не бояться этого варианта). Единственный недостаток - это накладные расходы на выделение и освобождение памяти. Такие расходы при интенсивном использовании могут действительно сильно нагружать при некой монотонной работе (в цикле или с постоянно запрашиваемым ресурсом). Например, у меня был случай, когда я использовал объект Context для отрисовки в ответ на WM_PAINT. Если у вас такая ситуация, то никто не запрещает кэшировать и повторно использовать объекты кучи. Для этого есть специальный формат фабричной функции, например: Files.File.NewReader (old: Reader): Reader. Если у вас есть кэшированный Reader, то вам его просто заново проинициализируют, без повторного выделения памяти.AVC писал(а): Интересно, нельзя ли расширить язык подобной конструкцией? На момент описания деструктора методы объекта могут быть не известны (если не унаследованы, то находятся ниже по тексту программы).Код: RECORD IMHO, синтаксически это вполне в духе языка, новых ключевых слов не надо.... CLOSE IF (f # NIL) & f.isOpen() THEN f.Close END END; Новых ключевых слов нет, но... Одна из ключевых особенностей языка - для меня - это отсутствие неявных вызовов. Если в одном случае я пишу NEW и получаю блок памяти, а в другом случае вызывается туча конструкторов, то я начинаю терять контроль над ситуацией. Это то же самое, что перегрузка оператора. Аналогично для стековых переменных: я вызываю процедуру, а на самом деле сначала выполняется десяток конструкторов для её локальных переменных, и я никак не могу на это повлиять. После конструкторов процедура первой же проверкой обнаруживает, что x1>x2, вызывает RETURN и вызывается куча деструкторов. Раз - и куда-то делась вся эффективность. По концептуальной чистоте фабричные функции гораздо лучше. Есть процедура, есть её явный вызов, поиск в исходнике сразу показывает, что и почему она делает. Без всяких скрытых механизмов. |
Автор: | Info21 [ Четверг, 23 Октябрь, 2008 10:06 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
К уже сказанному про BEGIN\CLOSE в RECORD: скорее всего, в этих секциях придется вызывать процедуры, определяемые ниже по тексту. При однопроходности компилятора это может быть проблематично. Повлечет хвост проблем с языком и компилятором. Trurl: а какие именно изменения предполгаются, примерно? |
Автор: | AVC [ Четверг, 23 Октябрь, 2008 10:19 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Александр Ильин писал(а): Единственный недостаток - это накладные расходы на выделение и освобождение памяти. <...> Если у вас такая ситуация, то никто не запрещает кэшировать и повторно использовать объекты кучи. Да, кэширование в нашем случае (Оберон/КП) - хороший прием.Его обязательно надо иметь в виду. (Наверное, возможны и какие-то иные его формы.) Александр Ильин писал(а): Одна из ключевых особенностей языка - для меня - это отсутствие неявных вызовов. Если в одном случае я пишу NEW и получаю блок памяти, а в другом случае вызывается туча конструкторов, то я начинаю терять контроль над ситуацией. Это то же самое, что перегрузка оператора. Аналогично для стековых переменных: я вызываю процедуру, а на самом деле сначала выполняется десяток конструкторов для её локальных переменных, и я никак не могу на это повлиять. После конструкторов процедура первой же проверкой обнаруживает, что x1>x2, вызывает RETURN и вызывается куча деструкторов. Раз - и куда-то делась вся эффективность. Это бесспорное достоинство Оберона. (Конечно, иной раз случается, что хорошо бы иметь какие-то возможности иных языков, в т.ч. Си++. Как правило, это можно пережить, а вот контроль над ситуацией - значительная ценность.)По концептуальной чистоте фабричные функции гораздо лучше. Есть процедура, есть её явный вызов, поиск в исходнике сразу показывает, что и почему она делает. Без всяких скрытых механизмов. Чтобы не связываться с запутанными механизмами, пока предлагаю только секцию CLOSE в процедурах. |
Автор: | AVC [ Четверг, 23 Октябрь, 2008 10:34 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Info21 писал(а): К уже сказанному про BEGIN\CLOSE в RECORD: скорее всего, в этих секциях придется вызывать процедуры, определяемые ниже по тексту. При однопроходности компилятора это может быть проблематично. Повлечет хвост проблем с языком и компилятором. Вполне возможно.Кроме того, наследование записей может вызвать дополнительные проблемы (может потребоваться уже целая цепочка вызовов BEGIN при инициализации объекта и CLOSE - при его финализации). Учитывая эти факторы (могут быть и другие), пока ограничиваю свою "инициативу" процедурной секцией CLOSE. Её реализация не должна представить особых трудностей. Код CLOSE должен вызываться при выходе из процедуры (в т.ч. при любом RETURN), а также в случае исключения (это тоже не проблема, т.к. отладчик, например, прекрасно находит всю информацию о процедурах в стеке). Сейчас вижу 2 основных назначения секции CLOSE:
|
Автор: | Александр Ильин [ Четверг, 23 Октябрь, 2008 10:51 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Это именно аналог finally, который, по моему мнению, можно реализовать библиотечно без правки языка. А если можно не править язык, то лучше его не править, по моему мнению. Единственное направление правки, которое я поддерживаю, - это повышение строгости. В целом признаю, что идея интересная и, возможно, удачная. Возможно введение секции CLOSE оправданно. Ведь ввели же её для модулей, хотя там тоже нет проблем библиотекой отделаться: простенький интерфейс к загрузчику, регистрация финализатора. В порядке конструктивной критики обращаю ваше внимание на то, что внутри секции CLOSE следует запретить использование RETURN. По крайней мере для процедур, возвращающих какое-то значение. |
Автор: | Александр Ильин [ Четверг, 23 Октябрь, 2008 10:54 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Trurl писал(а): Проблема в том, что Не вижу большой проблемы сделать обёртку, которая вместо TryHandler будет брать PROCEDURE (VAR msg: Exception). Правда, практического опыта у меня нет, там могут быть и свои подводные камни.
Код: TryHandler* = PROCEDURE (a, b, c: INTEGER); и чтобы обрабатывать исключения в процедуре, её надо приводить к видуPROCEDURE Try* (h: TryHandler; a, b, c: INTEGER); Код: PROCEDURE MyProc(a, b, c: INTEGER); Возможно в языке нужны другие средства, которые бы позволили сделать удобные библиотечные средства. |
Автор: | AVC [ Четверг, 23 Октябрь, 2008 11:04 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Александр Ильин писал(а): В целом признаю, что идея интересная и, возможно, удачная. Возможно введение секции CLOSE оправданно. Ведь ввели же её для модулей, хотя там тоже нет проблем библиотекой отделаться: простенький интерфейс к загрузчику, регистрация финализатора. Из модулей КП эта идея и "спёрта". Любопытно, что "деструкторы" здесь применяются не к объектам (что может порожать проблемы, в т.ч. с наследованием), а к модулям и процедурам, у которых как раз проблем с наследованием нет. Александр Ильин писал(а): В порядке конструктивной критики обращаю ваше внимание на то, что внутри секции CLOSE следует запретить использование RETURN. По крайней мере для процедур, возвращающих какое-то значение. Это разумная мысль.Но, возможно, еще лучше как раз разрешить RETURN (например, со значением, сигнализирующем об ошибке). Такой RETURN в секции CLOSE остановит обработку исключения (если RETURN в секции CLOSE не сработал, то продолжится "свертка" стека) и приведет к "обычному" выходу из функции/процедуры. Так сделано в XDS (с включенной опцией O2ADDKWD). Тогда, кстати, и дополнительное слово RETRY вовсе не понадобится (как реализующее слишком экзотическую возможность). |
Автор: | AVC [ Четверг, 23 Октябрь, 2008 11:14 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Немного глуповатый пример, взятый, кажется, из мануала XDS (если не ошибаюсь). Код: PROCEDURE DivBy (x, y: INTEGER); В нашем случае это будетBEGIN RETURN a DIV b EXCEPT RETURN MAX(INTEGER) END DivBy; Код: PROCEDURE DivBy (x, y: INTEGER); Я не говорю, что CLOSE стоит использовать именно так, а только хочу проиллюстрировать, как можно использовать RETURN в секции CLOSE.
BEGIN RETURN a DIV b CLOSE RETURN MAX(INTEGER) END DivBy; |
Автор: | Александр Ильин [ Четверг, 23 Октябрь, 2008 11:17 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
AVC писал(а): Александр Ильин писал(а): В порядке конструктивной критики обращаю ваше внимание на то, что внутри секции CLOSE следует запретить использование RETURN. По крайней мере для процедур, возвращающих какое-то значение. Это разумная мысль.Но, возможно, еще лучше как раз разрешить RETURN (например, со значением, сигнализирующем об ошибке). Код: PROCEDURE Zzz (a, b: INTEGER): INTEGER; Не забывайте, что мы говорим о finally, а не об except (или я не прав?). Finally выполняется всегда, и переопределение выходного значения с случае нормальной работы выглядит по меньшей мере странно. Вернуть код ошибки не получится, поскольку исключение не подавлено.
BEGIN RETURN a CLOSE RETURN b END Zzz; |
Автор: | AVC [ Четверг, 23 Октябрь, 2008 11:35 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Александр Ильин писал(а): Не забывайте, что мы говорим о finally, а не об except (или я не прав?). Finally выполняется всегда, и переопределение выходного значения с случае нормальной работы выглядит по меньшей мере странно. Согласен. Я именно забыл на минуту о том, что у нас finally, а не catch/except.В таком случае, действительно, надо запретить RETURN в секции CLOSE. Но хорошо бы ввести еще секцию EXCEPT (название пока не важно), чтобы можно было с помощью RETURN обработать исключение. Порядок следования секций BEGIN ... EXCEPT ... CLOSE, причем две последние секции необязательны (опциональны). Впрочем, возможны и какие-то альтернативы введению секции EXCEPT. Навскидку.
|
Автор: | AVC [ Четверг, 23 Октябрь, 2008 11:52 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Промежуточный итог обсуждения, IMHO, выглядит так.
|
Автор: | AVC [ Четверг, 23 Октябрь, 2008 12:01 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
AVC писал(а): Впрочем, возможны и какие-то альтернативы введению секции EXCEPT. Не стоит забывать и о способе обработки исключений, реализованном в ETH Oberon (с использованием метапрограммирования и вложенной процедуры).
Навскидку.
|
Автор: | Иван Горячев [ Четверг, 23 Октябрь, 2008 13:10 ] |
Заголовок сообщения: | Re: Нужны ли Оберону конструкторы, деструкторы и исключения? |
Если мне не изменяет память, в GPCP есть секция RESCUE - как раз аналог EXCEPT |
Страница 6 из 9 | Часовой пояс: UTC + 3 часа |
Powered by phpBB® Forum Software © phpBB Group https://www.phpbb.com/ |