OberonCore

Библиотека  Wiki  Форум  BlackBox  Компоненты  Проекты
Текущее время: Пятница, 29 Март, 2024 00:02

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




Начать новую тему Ответить на тему  [ Сообщений: 22 ]  На страницу 1, 2  След.
Автор Сообщение
 Заголовок сообщения: Структурность и исключения
СообщениеДобавлено: Четверг, 25 Март, 2010 06:01 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
Выделено: viewtopic.php?p=45023#p45023

Berserker писал(а):
Также стала абсолютно дикой концепция использования исключений для обработки ошибок
Вы просто не умеете их готовить. :wink:
Мне, к примеру, кажется совершенно диким код, в котором никогда не возникают ошибки, но они могут возникать в вызываемых процедурах. Мне, оказывается, за каким-то лядом надо это знать, и об этом заботиться (а может в какой-то процедуре тоже никогда не возникают ???). Такое ощущение, что не делом занимаешься, а ошибки ищешь - после каждого такого вызова.

Все дело в постулатах. Если некто постулировал, что всякий структурный блок имеет один выход, тогда рвет рубаху на груди, называя не признающих это - еретиками.
Сектанство это...

Для себя я сказал, что их два (рабочий, и исключение). И все (скажем три) правила структурной композиции естественным и очевидным образом формируют логику этого "второго" выхода.
И не имею никаких проблем с пониманием структуры :P


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Четверг, 25 Март, 2010 09:49 

Зарегистрирован: Четверг, 23 Апрель, 2009 18:01
Сообщения: 219
Я когда решал для себя, что есть структурность, то сделал аксиомой возможность свернуть любой блок и быть уверенным в его выполнении и в выполнении кода после него. Исключение считаю не более чем циклическим GOTO на выход из цепочки процедур и остановки на одном из верхних обработчиков. Так как результаты функций обрабатывать всё равно нужно, то лишнего кода нет. Вам по правилам придётся заключать в try/except вызов любой процедуры/функции.

Допустим, вы имели в виду то, что можете заключить блок из вызова 5-и функций и в случае ошибки хоть в одной из них, обработать её в блоке исключения:
TRY A; B; C; D; E; EXCEPT Error(..); END;
В структурном виде ничего не меняется:
IF A AND B AND C AND D AND E .... ELSE ... END;

Теперь вернёмся к доводу Ильи Ермакова. Возможность быстрого анализа блоков, реиспользования блоков кода.
Вы можете написать такой код с твёрдой уверенностью, что MyFile будет освобождён в конце функции незасивимо от внутреннего содержимого IF-блока? Я могу, и считаю это структурностью. И данное утверждение применимо к любому блоку ниже уровнем иерархически.
Изображение
Более того, возвращая результат ошибки в виде логического или числового значения, я позволяю функциям более высокого уровня использовать безопасно комплексные условия, а не ограждать себя серией обработчиков исключений на каждый тип ошибки, который нужно обработать по-своему.

Поэтому структурной программой считаю такую, где:
1) Нет BREAK/CONTINUE/EXIT/RETURN
2) Нет исключений
3) Нет GOTO
Своё видение не навязываю.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Четверг, 25 Март, 2010 13:31 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
Berserker писал(а):
Допустим, вы имели в виду то, что можете заключить блок из вызова 5-и функций и в случае ошибки хоть в одной из них, обработать её в блоке исключения:
TRY A; B; C; D; E; EXCEPT Error(..); END;
В структурном виде ничего не меняется:
IF A AND B AND C AND D AND E .... ELSE ... END;
Нет, я имел в виду другое
Ну например так:
Код:
TRY
  ...
  A0;
  ...
  WHILE(B0) DO
    ...
    C0;
    ...
    IF D0 THEN
      ...
      E0;
      ...
    END;
    ...
  END;
  ...
EXCEPT
......

(* пусть они все (A0-A6,B0-B6...E0-E6) имеют схожую (нетривиальную) логическую структуру*)
......

PROCEDURE E2;
  ...
  A3;
  ...
  WHILE(B3) DO
    ...
    C3;
    ...
    IF D3 THEN
      ...
      E3;
      ...
    END;
    ...
  END;
  ...
END E2;


......
PROCEDURE C6;
  ....
  ASSERT (очень_сложное_условие, 357 );
  (*ну или просто переполнение при арифметическом сложении*)
  ....
END C6;
Протаскивать ошибку из всего и везде - малопривлекательное удовольствие.
Мягко говоря.
Получающиеся при этом коды - дикие.
Не знаю, может Вам и понравится, попробуйте.... Я пробовал - мне не понравилось.
Подчеркну: для процедуры E2 никаких ошибок логически не существует, для нее это внешнее понятие, и чего делать с этими ошибками - она понятия не имеет.
И еще раз подчеркну самое главное - не вижу (для случая исключений) проблем со структурой


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Четверг, 25 Март, 2010 13:48 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Действительно исключительная ситуация (отказ, по предусловию, по переполнению и проч.) должна обрабатываться на одном уровне, в одном месте в процессе. Для этого достаточно библиотечного Try. Например, на уровне главного цикла встроенного или серверного приложения. В случае отказа именно на этом уровне принимается решение о логике восстановления системы.
Рассыпанными хаотично по программе TRY проблема живучести приложения не решается; без единой логики восстановления (какое состояние перманентно, какое теряется при сбое - и идёт перезапуск задачи с чистого листа...).
Кроме того, всегда говорю - представьте случай с сотнями параллельных задач (а даже для микроконтроллеров есть методы такого программирования; например система "Рефлекс" Евгения Зюбина).
Исключение кидать по стеку просто некому.

А ситуации, которые происходят не аварийно, а штатно, периодично (например, файл не найден или удалённый сервер не доступен) - это не предмет для исключений. Хотя иногда можно и их использовать, опять же, библиотечного Try достаточно (например, написали сценарий, обращающийся к неск. удалённым серверам, которые бывают недоступны, что-то снимающий с них - протаскивать коды успеха не хочется, шпигуем ASSERT-ами, и вешаем один Try на весь сценарий, плюс цикл - долбить, пока не будет успеха).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Четверг, 25 Март, 2010 15:21 

Зарегистрирован: Четверг, 23 Апрель, 2009 18:01
Сообщения: 219
Цитата:
Нет, я имел в виду другое
Ну например так:

Если я правильно вас понял, вы ASSERT-ы считаете ошибками? Я расцениваю ASSERT как категорическое утверждение, которое нельзя отловить и обработать. В вашем примере процедуры E2 предположим, что функции возвращают код ошибки (0 - всё хорошо). Тогда помогает простое разбиение на подпроцедуры:

Код:
PROCEDURE E2;
  PROCEDURE Sub2: BOOLEAN;
  BEGIN
    RESULT:=OK;
    WHILE RESULT = OK DO
      RESULT:=Sub4;
    END;
  END;

  ...SubN...

BEGIN
  RESULT:=BAD;
  IF
    Sub1 AND
    Sub2 AND
    Sub3
  THEN
    RESULT:=OK;
  END;
END E2;


Пример из реального кода привожу. К сожалению, не сохранил исходников до переработки, когда это были break-и, вложенные циклы и т.д. Переписывая код в структурном стиле, понял, что будет огромное кол-во условий и внутренних IF. Решение: декомпозиция.

Код:
PROCEDURE SelectLanguage (CONST LangName: STRING);
...
   (* SetLngFromRes *) {Пробует найти языковые данные в ресурсах}
   FUNCTION SetLngFromRes (Client: TClient; CONST LangName: STRING): BOOLEAN;
   ...
   END; // .function SetLngFromRes
   
   (* SetLngFromFilePack *) {Пробует загрузить файловый пак и найти там языковые данные}
   FUNCTION SetLngFromFilePack (Client: TClient; CONST LangName: STRING): BOOLEAN;
   BEGIN
   ...
   END; // .function SetLngFromFilePack
   
   (* SetLngFromFileUnit *) {Пробует загрузить файловый модуль и найти там языковые данные}
   FUNCTION SetLngFromFileUnit (Client: TClient; CONST LangName: STRING): BOOLEAN;
   BEGIN
   ...
   END; // .function SetLngFromFileUnit
   
   (* SetLngFromFileStrings *) {Пробует загрузить файловые строки с нужными языковыми данными}
   FUNCTION SetLngFromFileStrings (Client: TClient; CONST LangName: STRING): BOOLEAN;
   BEGIN
   ...
   END; // .function SetLngFromFileStrings
   
BEGIN
   ...
   FOR i:=0 TO Clients.Count - 1 DO BEGIN
      Client:=TClient(Clients.Objects[i]);
      IF Client.Language <> LangName THEN BEGIN
         // Смотрим, не является ли выбираемый язык языком по умолчанию для модуля
         IF Client.DefLangName = LangName THEN BEGIN
         ...
         END // .if
         ELSE IF
            (NOT SetLngFromRes(Client, LangName)) AND
            (NOT SetLngFromFilePack(Client, LangName)) AND
            (NOT SetLngFromFileUnit(Client, LangName))
         THEN BEGIN
            SetLngFromFileStrings(Client, LangName);
         END; // .elseif
      END; // .if
   END; // .for
END; // .procedure SelectLanguage


Эти строки:
Цитата:
(NOT SetLngFromRes(Client, LangName)) AND
(NOT SetLngFromFilePack(Client, LangName)) AND
(NOT SetLngFromFileUnit(Client, LangName))
...
SetLngFromFileStrings(Client, LangName);

содержат, фактически, основной код, вложенные циклы, сложные условия. Как видно, после декомпозиции проблемы не стало.

Возвращая коды ошибок, вы предоставляете право функциям верхнего уровня самим решать, как обрабатывать ошибки, и стоит ли их обрабатывать.

В чём по вашему структурность программы, если из произвольного блока можно сделать произвольный вылет, который вернётся только где-то там на одном из верхних уровней в установленным когда-то обработчике? Программист больше не уверен в целостности конструкций IF-ELSE, WHILE, PROCEDURE END и т.д. Какие инварианты и доказательства программ? Может кому-то и проще писать:

Код:
TRY
много вызовов опасного кода без разбора
FINALLY
...
END;


...как советует Влад. А в чём тогда смысл вызыва исключения, если его можно таким образом тихо подавить и даже не знать, что там было и почему? Может быть причина ошибки - код программы, а не внешние условия.
В истинно структурном коде, если мы откроем файл без проверки результата, то ничего не произойдёт. А вот вызов FileRead встретит ASSERT(Handle <> INVALID_HANDLE_VALUE) и такой ассерт просто нельзя подавлять. А у вас можно написать где-то там далеко TRY FINALLY и забыть про ошибки вообще. Но они всплывут, а ваша программа не станет безопаснее.

Чтобы обсудить вопрос более формально, приведу три "теоремы":

I.
Пусть любая функция, чей результат может быть неуспешен, возвращает либо BOOLEAN либо INTEGER как флаг ошибки. При этом для INTEGER 0 - нет ошибки, MAX(INTEGER) - неизвестная ошибка, а множество (0; MAX(INTEGER)) - множество кодов ошибок. Тогда любой код, где вы предлагаете использовать обработку исключений, сравнительно легко переписывается в структурном стиле без обработки исключений.

II.
Если в функции каждое последующее действие требует успешного результата предыдущего, а число действий велико, то код функции разбивается на подфункции так, что кол-во действий находилось в рамках 1-7.

III. Структурный код - это код, не содержащий никаких операторов выхода из текущего блока, а именно: BREAK/CONTINUE/EXIT/RETURN/RAISE.

"Выполнение условного оператора if"
Изображение

В Обероне не 2007/ББ есть два нарушения, позволяющих писать неструктурный код: RETURN из произвольного места процедуры и LOOP EXIT.

Википедия писал(а):
Структурное программирование — методология разработки программного обеспечения, в основе которой лежит представление программы в виде иерархической структуры блоков. Предложена в 70-х годах XX века Э. Дейкстрой, разработана и дополнена Н. Виртом.

В соответствии с данной методологией
Любая программа представляет собой структуру, построенную из трёх типов базовых конструкций:
-) последовательное исполнение — однократное выполнение операций в том порядке, в котором они записаны в тексте программы;
-) ветвление — однократное выполнение одной из двух или более операций, в зависимости от выполнения некоторого заданного условия;
-) цикл — многократное исполнение одной и той же операции до тех пор, пока выполняется некоторое заданное условие (условие продолжения цикла).
В программе базовые конструкции могут быть вложены друг в друга произвольным образом, но никаких других средств управления последовательностью выполнения операций не предусматривается.
Повторяющиеся фрагменты программы (либо не повторяющиеся, но представляющие собой логически целостные вычислительные блоки) могут оформляться в виде т. н. подпрограмм (процедур или функций). В этом случае в тексте основной программы, вместо помещённого в подпрограмму фрагмента, вставляется инструкция вызова подпрограммы. При выполнении такой инструкции выполняется вызванная подпрограмма, после чего исполнение программы продолжается с инструкции, следующей за командой вызова подпрограммы.
Разработка программы ведётся пошагово, методом «сверху вниз».


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 30 Март, 2010 01:57 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
Berserker писал(а):
Если я правильно вас понял, вы ASSERT-ы считаете ошибками? Я расцениваю ASSERT как категорическое утверждение, которое нельзя отловить и обработать
Считайте для удобства, что это некая объективная реальность (на которую ни Вы ни я не можете повлиять), введенная теми (скажем - разработчиками железа), кто все-таки считает этот механизм не противоречащий струкурному программированию.
Например, исключение, возникающее в FPU при обыкновенном сложении.
Разницы - НИКАКОЙ. Копья одни и те же ломаются...

Berserker писал(а):
В вашем примере процедуры E2 предположим, что функции возвращают код ошибки (0 - всё хорошо). Тогда помогает простое разбиение на подпроцедуры:
Давайте предположим более жизненную вещь.
Процедура E2 - команда внешнего модуля, связанного с нашими "еще нижележащими" через процедурные типы.
Давно проверенная и оттестированная. Типа - эталон надежности. И всех многие годы она устраивала.
И, возможно, у Вас даже и исходников нет.
Но тут приключилась беда, Вы начали работать в некой новой области знаний. И даже еще не выяснили причин очень-очень редких сбоев... Может через год, по результатам исследований - научное открытие сделаете.
И что теперь - для проведения таковых "исследований" все переписывать с возвратами кодов ошибки :?:

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

Berserker писал(а):
Пример из реального кода привожу
Соревноваться примерами - не самое лучшее занятие...
Но у меня тоже есть пример.
Есть у нас элемент MathParse - интерпретаро в мат.выражений в run-time. Там разбор "рекурсивный вниз" - вложений по самое небалуйся, в общем.
И два релиза - для FPC и для Дельфи. По некоторым субъективным причинам, я просто не знал как там (в FPC) исключения перехватывать (в смысле - экономно, для Дельфей есть микропримочка от Кладова)
И испытал все прелести возвратов кода ошибки, и ее анализа в каждой второй строке.
Уверяю, мне было на что поглядеть, чтобы сделать заключение - дурдом на каникулах. Хотя и работающий.
А Дельфячий вариант (с исключениями, даже и не проверяю - можно делить на нуль, или нет...) работает все равно надежнее. Можете верить, можете - нет. А для меня это просто экспериментальный результат. Многолетний, можно сказать.

Berserker писал(а):
В чём по вашему структурность программы, если из произвольного блока можно сделать произвольный вылет, который вернётся только где-то там на одном из верхних уровней в установленным когда-то обработчике?
Читаем внимательней - я Вам с самого начала сказал: измените аксиоматику.
Всякий структурный элемент имеет ДВА выхода. Даже сложение двух чисел
И что занимательно, никто ведь не изменяет множество входных состояний, соответствующих некому заданному выходному. Что за кошмарное беспокойство про порушенность "системы доказательств" - не пойму.
А структурность "по-нашему" заключается в том, что всякий структурный элемент, полученный по правилам структурной композиции может быть использован еще раз как базовый.
Вот для RETURN и EXIT - это не так. А для rise,assert, и прочего аналогичного - так.
И не надо путать грешное дело с праведным.
Никто никогда вышеупомянутый EXIT не называл элементом структуры
А SEH - в своем названии содержит слово "структурный". Или как, дураки название придумывали, что ли :?:

Berserker писал(а):
Чтобы обсудить вопрос более формально, приведу три "теоремы"
Молодца :!:
Осталось сделать последний шаг - делать все это в уме. Не надо портить коды. Делаться (исполняться) будет как Вы и написали, а коды корежить не будем.
И жизнь станет намного проще. Как и у меня - никаких проблем со структурностью исключений


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 30 Март, 2010 03:15 
Аватара пользователя

Зарегистрирован: Суббота, 19 Ноябрь, 2005 15:59
Сообщения: 803
Откуда: Зеленоград
IMHO, для КП в ряде ситуаций использование библиотечной процедуры Kernel.Try практически обязательно.
Например, при написании DLL (за исключением каких-то совсем вырожденных случаев).

Galkov писал(а):
Вот для RETURN и EXIT - это не так. А для rise,assert, и прочего аналогичного - так.
И не надо путать грешное дело с праведным.
Вот и Вы туда же. По каким-то таинственным причинам ("досрочный") RETURN считается неструктурным. Чем он хуже тех же исключений?
Возможно, путаница идет от сомнительной (IMHO) интерпретации выражения "один выход".
Можно понимать так, что следует поставить единственный RETURN в самом конце функции.
А можно понимать так, что, по завершении работы процедуры, управление будет передано в одну единственную точку в вызывающей процедуре.
Не оспаривая полезности единственного RETURN в некоторых случаях, стоит заметить, что такой стиль может привести к рецидивам паскалевских безобразий с использованием искусственных вспомогательных переменных. (Другая, основная (и родственная), причина их размножения в Паскале -- полная схема вычисления логических выражений, что приводило к уродливости циклов и невозможности нормально сформулировать на Паскале даже линейный поиск. Учитывая популярность линейного поиска, это серьёзный недостаток языка.)
IMHO, если значение функции уже известно, то во многих случаях правильнее всего вернуть его немедленно, не мучая программиста-читателя.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 30 Март, 2010 08:48 

Зарегистрирован: Четверг, 23 Апрель, 2009 18:01
Сообщения: 219
Galkov писал(а):
Например, исключение, возникающее в FPU при обыкновенном сложении.

Berserker писал(а):
Считаю необходимым применение исключений только там, где это действительно нужно - в математических операциях (TRY a+b EXCEPT MathError END).

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

Galkov писал(а):
И что теперь - для проведения таковых "исследований" все переписывать с возвратами кодов ошибки
Если говорить правду - очень большая глупость.

Переписывать часть готового модуля/проекта, рассчитанного на исключения действительно неразумно.

Galkov писал(а):
Есть у нас элемент MathParse - интерпретаро в мат.выражений в run-time. Там разбор "рекурсивный вниз" - вложений по самое небалуйся, в общем.

У меня как раз стояла задача написать интерпретатор выражений в стиле Excel с поддержкой функций и констант. Его я и переписывал с нуля. Обработка (а не вызов) исключений понадобились только в обработчиках мат.операторов. Здесь очень удобной оказалась предопределённая переменная RESULT. В итоге почти все условия и вызовы завязаны на ней.

Galkov писал(а):
Уверяю, мне было на что поглядеть, чтобы сделать заключение - дурдом на каникулах. Хотя и работающий.

Влад приводил в ЛС похожий пример. Ответ был: если программист способен справляться традиционными структурными средствами и код не становится кашей, а сохраняет лаконичность, то нужды в обработке ошибок исключениями нет и это скорее преимущество, чем недостаток, так как труда перейти на TRY..EXCEPT не составит, а вот обратно, по всей видимости, для многих тяжело.

Galkov писал(а):
измените аксиоматику.
Всякий структурный элемент имеет ДВА выхода.

Нужно и название парадигме менять. С изменением аксиоматики изменяются и свойства кода. В моём предложении у каждого блока только один выход и я могу 100% сказать, где и как будет исполняться код. А выброс исключения - прыжок в неизвестность. Кроме того, мой аргумент про небезопасный код в силе:

Код:
TRY
  Main;
FINALLY
...
END;


В вашей программе больше нет ошибок. Магия, не правда ли? В структурном коде обработка ошибок идёт явно и на каждом шаге сохраняется контроль над состоянием программы. Процедура не может сделать скачок на несколько уровней выше, причём скачок низкоуровневый, ну чем не GOTO?

Я вас ни в коем случае не переубеждаю. Несомненно, опыта у вас больше, но в сложности кода без использования исключений очень сомневаюсь и буду сомневаться, пока не смогу решить задачу простым разбиением на подфункции и использованием кодов ошибок.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 02:14 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
AVC писал(а):
Вот и Вы туда же. По каким-то таинственным причинам ("досрочный") RETURN считается неструктурным. Чем он хуже тех же исключений?
Не-не :) В "наших" привычках вовсе не числится хождение "туда же"... Скорее наоборот.
Припоминается мне определение от Ильи (по памяти): у меня есть возможность включить данную структурную единицу в состав другой структуры, не взирая на ее содержание
Мое утверждение: это НЕ ТАК для структур содержащих RETURN и EXIT (еще как "взирать" придется), а вот за rise (или assert) можно в этом плане не беспокоиться.
Этим и отличаются
У меня получилось убрать ореол таинственности :?:


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 03:44 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
Berserker писал(а):
При этом обработчик находится там же, где и охраняемый код.
Дулю с маком.
Напомню, что мы придерживаемся концепции не только раздельной компиляции, но и раздельного авторства кодов.
А в этой концепции совершенно жизненными становятся ситуации, когда в точке обнаружения криминала - совершенно непонятно что с ним делать. А там где можно принять логичное решение - неизвестно будут ли криминалы вообще.

Berserker писал(а):
Переписывать часть готового модуля/проекта, рассчитанного на исключения действительно неразумно.
Вы наверное непоняли... Посмотрите, я говорил про процедуру E2, которая вовсе не была рассчитана на исключения. Она просто таких словов не знала !!!
И здесь вопрос вовсе не в том, считаете ли Вы (или я) это разумным. Мы здесь совершенно не причем: у нас может просто не быть исходников.
Такова жизнь - в ней бывает и такое. И я вовсе в этом не виноват, между прочим :)

Berserker писал(а):
Обработка (а не вызов) исключений понадобились только в обработчиках мат.операторов. Здесь очень удобной оказалась предопределённая переменная RESULT. В итоге почти все условия и вызовы завязаны на ней.
Правильно ли я понял, что вместо того, чтобы не писать НИЧЕГО при обработке мат.операторов (в т.ч. и просто сложение), Вы отключали прерывания FPU, а после выполнения вычислительной операции - проверяли флаги (не будем уточнять какие) сопроцессора :?:
Ну и естественно - возврат параметров FPU на место...
Если нет - Ваши коды были некорректны, мне кажется
Цена - коды, которые ненужны никому, и гробят быстродействие. Зачем-то... Причина - не более чем аллергия на исключения.
Про читаемость... Вы вообще-то чего писали: "калькулятор", или "проверятель корректности" входных данных ??? :wink:

Berserker писал(а):
Ответ был: если программист способен справляться традиционными структурными средствами и код не становится кашей, а сохраняет лаконичность, то нужды в обработке ошибок исключениями нет и это скорее преимущество, чем недостаток, так как труда перейти на TRY..EXCEPT не составит, а вот обратно, по всей видимости, для многих тяжело
Ну я же Вам объяснил, что способен. Коды что ли привести ??? это несложно, они в репозитории лежат...
Добавлю, что способен еще и отличить разницу в эффективности "просто вычислений", от вычислений с проверками по каждой арифметической операции. А если не по каждой (ну например, только проверки на ноль перед делением), то и заметить разницу в надежности.
И еще добавлю, что задачей программиста (мне кажется) является не только "смочь" написать коды произвольной дикости, но еще и некие качественные характеристики этого кода.
Скажем - эффективность, хотя это и не единственное требуемое качество.

Berserker писал(а):
Нужно и название парадигме менять. С изменением аксиоматики изменяются и свойства кода
Нужно не название менять, а свое понимание происходящего вокруг нас.
Грубо говоря - это концептуальная разница между "математиками" и "физиками" :D
Первые создадут теорию, и жутко обижаются, когда она перестает соответствовать жизни. Несогласных причисляют к "еретикам". А у вторых - вывести теорию из той самой жизни. И здесь уже матаппарат есть не цель, а лишь средство. В общем - не самое главное (да простят меня математики).
Мое утверждение: если у структуры один выход - это слишком грубое приближение к реальной жизни.
В подавляющем числе случаев верное, и теоретическое описание - проще.
Но то, что не абсолютно всегда применимое - не моя придумка, и осознанная настолько, что сопровождается аппаратно (SEH - это + еще и совершенно определенные требования к среде исполнения, конечно же)

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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 06:03 

Зарегистрирован: Суббота, 07 Март, 2009 15:39
Сообщения: 3261
Откуда: Астрахань
Galkov писал(а):
Berserker писал(а):
При этом обработчик находится там же, где и охраняемый код.
Дулю с маком.
Напомню, что мы придерживаемся концепции не только раздельной компиляции, но и раздельного авторства кодов.
А в этой концепции совершенно жизненными становятся ситуации, когда в точке обнаружения криминала - совершенно непонятно что с ним делать. А там где можно принять логичное решение - неизвестно будут ли криминалы вообще.

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


Последний раз редактировалось Валерий Лаптев Вторник, 27 Апрель, 2010 14:22, всего редактировалось 1 раз.

Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 07:39 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Galkov писал(а):
Мое утверждение: если у структуры один выход - это слишком грубое приближение к реальной жизни.
В подавляющем числе случаев верное, и теоретическое описание - проще.


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


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 12:37 

Зарегистрирован: Четверг, 23 Апрель, 2009 18:01
Сообщения: 219
Galkov писал(а):
Правильно ли я понял, что вместо того, чтобы не писать НИЧЕГО при обработке мат.операторов (в т.ч. и просто сложение), Вы отключали прерывания FPU, а после выполнения вычислительной операции - проверяли флаги (не будем уточнять какие) сопроцессора

Есть два пути. Первый - компилировать программу с отключёнными исключениями при FPU-ошибках. Тогда нужно проверять результат на NaN, +-Infinity. Во втором случае использовать исключения. Их можно и нужно использовать в коде, который содержит атомарную операцию и не содержит искусственного вызова исключений (raise), если блок охраны идёт сразу за атомарной операцией.

Код:
TRY a+b EXCEPT MyCode END = IF NOT System.SafeSum(a, b) THEN Mycode END;


Мы уже обсуждали это с Владом. Можно написать эти самые SafeSum/Div/Mul, можно использовать исключения. Структурность не ломается. Запись оригинальная, просто, в силу ограничений имеющегося интрументария. Также ничего страшного нет в том, чтобы ловить исключения отдельных потоков, при условии, что они после этого будут тихо убиты и что они сама RAISE не вызывают.

Ошибку можно передавать и через переменную потока, а функции возвращать будут только её признак (boolean);

Код:
SetError(TMyError.Create(...));
RESULT:=FALSE;
...
PROCEDURE SetError (ErrObj: TErrorObj);
BEGIN
  FreeAndNIL(Error);
  Error:=ErrObj;
END;

Фактически, мы ликвидировали таким образом сложность кодов возврата (их просто нет, есть флаг ошибки). А вот продумать иерархию классов ошибок всё равно нужно, как и поля объектов ошибок. То бишь сложность в целом не убралась, разве что частично, так как теперь ошибки - целые структуры. То же самое делает и RAISE TMyError, только ломая блоки и тем самым подрывая весь смысл классического структурного программирования.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 13:45 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
Илья Ермаков писал(а):
Не слишком и не грубое, но что есть класс случаев, где грубое - это так
Сойдемся на том, на том, что до той же степени "грубое", насколько и классическая механика "груба" в сравнении с СТО.
Это я к тому, что в таковой эволюции парадигм нет ничего нового... Что-то похожее где-то и когда-то уже было (в науке, имеется в виду)


Илья Ермаков писал(а):
Однако есть и другой момент: в линейном тексте просто нет возможности внятно представлять коммутацию структур с числом выходов больше одного (ср. с Драконом).
А зачем представлять, если поведение этого "представления" предсказуемо до безобразия :)
Ну предположим, что мы напряглись, и возвели для себя (зачем-то) аксиому а-ля-COM-технология: не бывает иных процедур, акромя как возвращающих тип HRESULT
((между прочим, извлечение данных из массива по индексу к такому типу процедур не относится :lol: ))
Спрашивается, чего должна делать наша программка, не знающая самого слова "ошибка".
Все очевидно - и никакой свободы у программиста здесь нет. Зато есть возможность сделать ошибку, отклонившись от данной очевидности.
Ради какой такой великой цели мы даем (предположительно) ему эту возможность :?:
Утверждение - нет такой великой цели, кроме хаоса в голове.
Далее два варианта: можно тратить ресурсы компа, проводя в жизнь идеологию одного выхода. Например, проверять индексы массивов "в ручную" (компилятор-то ведь исключение сгенерирует!!!). Или тестировать все NEW операторы (а вдруг память кончилась!!!)
А можно переструктурировать мысли в голове. Результат тот же, а компу меньше работы. Вот этот вариант я и выбираю.

Да, мне понятно, что затраты на проверки порой копеечные. Но бсуждать количество этих копеек я буду только после того, как пойму ради чего. Без убедительных свидетельств объективности данных "трудностей" - нет и предмета для обсуждения.
Сначала - ради чего, а уже потом - количество копеек :D


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 14:12 

Зарегистрирован: Вторник, 11 Август, 2009 11:44
Сообщения: 516
Откуда: Бердск
Berserker писал(а):
То же самое делает и RAISE TMyError, только ломая блоки и тем самым подрывая весь смысл классического структурного программирования
Ну надо же, как трудно с Вами... А ведь мы еще даже не начали беседу о двухпроходных (в смысле, "восстанавливающих" сломанную программу) исключениях :lol:
Это Вы так думаете, что чего-то там ломается, а на самом деле НИКТО НИЧЕГО НЕ ЛОМАЕТ :!:

Давайте подойдем с другого боку......
Вы используете массивы :?: Вопрос: какое право Вы имеете обращаться к элементу по индексу!!! Ведь там у нутре вызывается ИСКЛЮЧЕНИЕ, которое (по Вашему!!!) ломает к чертовой матери всю структуру Вашей программы.
Типа (говоря Вашими словами) нельзя сделать никакого разумного логического заключения о постусловиях.
Как же это Вы живете со "сломанной" структорой-то - не пойму... :)

И что же это за бездарные люди написали ББ, в котором вызов команды Вашего модуля - не более чем мелкий эпизод из жизненного цикла BlackBox.exe
И что занимательно - никто Вас (как автора модуля) не заставляет возвращать коды ошибок. Перехватывают себе исключения (не напрягаясь за диспуты про структурность), да и запускают некую "команду", a.k.a. "дежучер". Да хоть сто раз... и все в течении одного жизненного BlackBox.exe.

Видите ли, коллега, если я и дальше буду развивать Ваше понимание "Структуры и Доказательности" (мое - чуть-чуть ДРУГОЕ), то авторам ББ мало не покажется :D
Так как, будем ее развивать, или что :?:


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 14:40 

Зарегистрирован: Четверг, 23 Апрель, 2009 18:01
Сообщения: 219
Вы в пример приводите запуск подпроцесса (код модуля, поток) и его тихую ликвидацию через перехват исключения с той целью, чтобы вся система продолжала работу. Я не против.
Berserker писал(а):
Также ничего страшного нет в том, чтобы ловить исключения отдельных потоков, при условии, что они после этого будут тихо убиты и что они сама RAISE не вызывают.

Если вы хотите записывать в логи исключения, то пожалуйста, перехватывайте:
Код:
TRY
  Main;
EXCEPT
  LogErrors; HALT;
END

Но не стоит превращать средство обработки исключительных ситуаций в средство обработки обычных ситуаций (изначально предусмотренных). Если вы открываете файл, то вы предполагаете, что он может и не открыться, так как поведение функции зависит от внешней среды. Возврат ошибки файловой системы это не исключительная, а рядовая ситуация. Для массивов или списков индексы нужно проверять, если индекс пришёл из внешнего источника. Ошибка NEW для программы фатальна. Можно перехватить её на верхнем уровне, показать диалог и всё равно прикрыть программу, так как её дальнейшее поведение некорректно. А если, делая запрос на выделение памяти, вы всё же рассчитывали на ошибку, то вызывайте какой-нибудь SafeNew с внутренней обработкой и возвратом BOOLEAN.

Иными словами, я не против обработки исключений как таковой, ибо это попросту глупо пытаться обойтись без неё (как в ББ). Тем не менее, исключения должны применяться только для обработки именно исключительных ситуаций (мат.операции (со)процессора, отказ работы потока, отказ работы модуля, экранирование языковых конструкций, которые вызывают исключения).


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 21:50 
Модератор
Аватара пользователя

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


А что в ББ?
Как это - "без неё", если "непотопляемый" рабочий цикл среды как раз её и предоставляет.
Сбой - распечатали память - готовы выполнять следующую команду. Не нужна память - регистрируем обработчик. Совсем особый случай - используем рантаймовый Try.
Как раз по-вашему и есть.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 21:55 

Зарегистрирован: Четверг, 23 Апрель, 2009 18:01
Сообщения: 219
Имелось в виду отсутствие конструкций на уровне языка без необходимости системных хаков (Kernel.Try). Например, для элементарного калькулятора чисел integer a+b может вызвать переполнение.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Вторник, 27 Апрель, 2010 21:58 
Модератор
Аватара пользователя

Зарегистрирован: Понедельник, 14 Ноябрь, 2005 18:39
Сообщения: 9459
Откуда: Россия, Орёл
Berserker писал(а):
Имелось в виду отсутствие конструкций на уровне языка без необходимости системных хаков (Kernel.Try).


Если нужно, его можно завернуть в приличный совершенно вызов вида Try(handler: PROCEDURE(VAR par: ANYREC), VAR par: ANYREC) - и использовать, как обычно и делают.


Вернуться к началу
 Профиль  
 
 Заголовок сообщения: Re: Структурность и исключения
СообщениеДобавлено: Среда, 28 Апрель, 2010 07:02 
Аватара пользователя

Зарегистрирован: Пятница, 25 Ноябрь, 2005 12:02
Сообщения: 8500
Откуда: Троицк, Москва
Berserker писал(а):
Имелось в виду отсутствие конструкций на уровне языка ...
Да что за манера всё в язык пытаться запихнуть.
Столько раз перемолото уже.


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

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


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

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


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

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