OberonCore

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

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




Начать новую тему Ответить на тему  [ Сообщений: 100 ]  На страницу Пред.  1, 2, 3, 4, 5
Автор Сообщение
СообщениеДобавлено: Вторник, 08 Август, 2017 13:51 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
ПСВ100 писал(а):
В Rust-е, фактически, такой же подход в обработке ошибок как и в Оберонах (если я правильно их понимаю). Имеется "паника" -- аналог assert-а в Обероне (аварийный останов программы без каких-то прямых перехватов и восстановления). Если не ошибаюсь, где-то здесь в соседней теме про программирование "под доказательство" вы сами отмечали о важности assert-ов.

Строго говоря, в Расте не совсем такой подход к обработке ошибок, как в Оберонах. Можно устроить такой трей-кач, что главный архитектор проекта не поймёт откуда он вылез. В Оберонах -- любой assert даёт квалифицированное исключение. Т. е. по сути -- программное прерывание. С остановкой, или обработкой -- но квалифицированное!! В Расте это далеко не так.
ASSERT -- первое средство в пре-, ин- и постусловиях. Контрактное программирование оказывается простейшей штукой при таком подходе.

Цитата:
Однако, я не думаю, что в Обероне "паникуют" (т.е. окончательно прерывают программу), напр., при неудачном открытии файла.

Разумеется, нет. Отсутствие файла на диске вообще по определению не может быть источником исключения)) Это, кстати, уже многократно озвученная проблема: на исключения понавесили то, чем они не должны заниматься по определению.

Цитата:
что по-своему и полезно: пусть безобразно, но зато однообразно). К тому же модно подталкивать к коду в стиле:
"a = OpenFile(...).MkString(...).Split(...)" , где без исключений ни как.

Однообразие, лучший вариант безобразия, согласен. Действия профессионала предсказуемы, но в мире полно любителей. Однообразие есть обстоятельства смягчающие вину. Расстрэлать! Но, нэ больно!

Цитата:
Достаточно во многих случаях, но семантика результатов может быть и иной, к примеру, ...

Именно это и является источником синих экранов смерти)) Зачем в системном программировании, где каждый чих равносилен взрыву атомной бомбы -- усложнять семантику через неоправданное упрощение? (в данном случае)

Цитата:
...хотя в целом тут и при "кодах ошибки", т.е. и без исключений необходимо выкручиваться, и не только "классическим" способом -- через временные объекты и окончательный "swap" при успешной транзакции

Да!!! Это неизбежное зло!! Так зачем что-то выдумывать, если возвращаемые коды, при промышленном программировании -- нужно анализировать ВСЕГДА!!!

Цитата:
...и утвердить, что, как минимум, исключения не обеспечивают "свёртку невообразимо сложного графа реакции на все потенциально возможные ошибочные ситуации" (а в целом -- не только ошибочные).

Утверждаю.
Если бы народ пользовал ASSERTы в рамках различного рода условий -- не моогло бы исключение подняться из глубин на верхний уровень. Это самый настоящий технический долг, перекладываемый на пользователя (в терминах Ф. В.)

Цитата:
Но одновременно и подход без "прикладных" исключений сам по себе ни как не реализует "невообразимо сложного графа реакции на все возможные ситуации".

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

Цитата:
В рамках "Оберон-подхода" (назову это так) напрасно игнорируется подход управления "от данных", как здесь:

Оберон не игнорирует такой подход)) Подход "от данных" просто перпендекулярен Оберон-технологии.
Данные пассивны. Как бы не требовался динамизм в системе, лично я -- против, чтобы данные управляли программой (разумеется в проблеме лексического анализа текст управляет ходом программы, но это из другой оперы).

Цитата:
Иными словами, самого по себе минимализма в стиле Оберон-а не достаточно, иначе подобные темы здесь и не возникали бы.

Оберон-технология не решает ЧТО сделать. Оберон-технология решает КАК сделать. И из-за ограничений накладываемых на заведомо ложные варианты, да -- местами с непривычки многим будет неудобно.
Но это не потому, что "чемоданчик с минимально необходимым набором инструментов" через чур минимален.
Это от дурных-с привычек-с...))


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 08 Август, 2017 21:22 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
prospero78 писал(а):
Оберон-технология не решает ЧТО сделать. Оберон-технология решает КАК сделать. И из-за ограничений накладываемых на заведомо ложные варианты...

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

prospero78 писал(а):
Разумеется, нет. Отсутствие файла на диске вообще по определению не может быть источником исключения))

Возьму пример отсюда (первое, что попалось под руку при быстром гуглении):
http://www.hardforum.ru/t92599/
Код:
MODULE TestAscii;
        IMPORT ObxAscii, Out;

        CONST
                 lf = 0DX;

        PROCEDURE Test*;
         VAR
                 t : ObxAscii.Text;
                 ch : CHAR;
         BEGIN
                 t := ObxAscii.Open(NIL, "Obx/Mod/Test.txt");
                 WHILE ~ObxAscii.Eot(t) DO;
                         ObxAscii.ReadChar(t, ch);
                         IF ch = lf THEN
                                 Out.Ln();
                         ELSE
                                 Out.Char(ch);
                         END;
                 END;
         END Test;
 END TestAscii.

Рассмотрим без всяких претензий к истинности API и пр., важен всего лишь сам следующий принцип. Как я понимаю, функция "open" должна вернуть невалидный дескриптор файла в случае неуспеха (м.б. как nil, за конкретной информацией о проблемах нужно куда-то обращаться отдельно, не важно). Итак, условно Оберон-технология утверждает:
prospero78 писал(а):
Так зачем что-то выдумывать, если возвращаемые коды, при промышленном программировании -- нужно анализировать ВСЕГДА!!!

Но Оберон-технология здесь не "решает КАК сделать". Подозреваю, что компилятор программу проглотит не задумываясь.
И единственный вариант:
prospero78 писал(а):
Если бы народ пользовал ASSERTы в рамках различного рода условий -- не моогло бы исключение подняться из глубин на верхний уровень. Это самый настоящий технический долг, перекладываемый на пользователя (в терминах Ф. В.)

Т.е., и лишь во время исполнения, если была ошибка открытия файла, программа вылетит в "квалифицированный assert" при ObxAscii.Eot (предполагаю, что всё-таки здесь не возвращается false при кривом аргументе, ну ли при ObxAscii.ReadChar). И то, если assert-ы "включены" и разработчики модуля ObxAscii "исполнили свой долг" -- влепили assert-ы (но я не в курсе, м.б. assert-ы не "отключаются" в Оберонах вообще "для надёжности", но тогда непонятна ситуация -- зачем двойная работа: "прикладные" проверки и неотключаемый анализ в assert).

prospero78 писал(а):
Строго говоря, в Расте не совсем такой подход к обработке ошибок, как в Оберонах. Можно устроить такой трей-кач, что главный архитектор проекта не поймёт откуда он вылез.

В Rust-е из трей-кач ничего не вылазит (нет там "классических" исключений), кроме результата выражения. Здесь обычно open вернёт дескриптор файла, запакованный в аля Result. Воспользоваться им без извлечения из контейнера не получится, а следовательно будет выполнена и проверка.

В языках с "классическим" механизмом исключений вылет exception при open, как минимум, выдаст проблему сразу же, которую не проигнорируешь (и считаем, что в общем случае это постоянные неотключаемые runtime-проверки).

На фоне техник выше непонятно, как Оберон "нагибает" пользователя делать проверки. "Исключения" выкинуты, но в замен -- только тестирование и в этом вся надёжность? (чтобы в конечном итоге сработали хрен знает где хотя бы assert-ы в базовом языковом API, которыми пронизаны потроха основных средств платформы, насколько я понимаю. К слову, в той же Esterel-платформе наличие/отсутствие данных при операциях (в т.ч. и ошибки) -- естественное явление, обзываемая там "clock"-ами для данных, которые есть часть автоматического вывода типа, контроль и удобства значительно выше, чем обычная техника через алгебраические типы данных как в том же Rust-е).

Т.е. в Обероне "самый настоящий технический долг" полностью перекладывается на пользователя?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 08 Август, 2017 21:56 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
Проблема вот в чём. Оберон, предлагает инструмент, для сделать "как надо". Но если программист желает использовать SYSTEM.GET\SYSTEM.PUT по старой привычке -- Оберон препятствовать не станет. Так можно делать, хотя и не нужно.
ASSERT -- это гарантия того, что параметр подлежащий контролю ведёт себя адекватно. Чем их больше, тем проще отлавливаются баги. Но Оберон не требует их использования. Программист, если считает себя богом -- ради того же самого бога -- может жрать кактусы килограммами.
ASSERT отключать можно. Но смысла нет, пока программа не отлажена. А в ряде случаев -- вообще не надо отключать. Сокрытие ошибки может стоить очень дорого. Что касается машинных затрат, тут вообще такими вещами можно пренебречь.
Нет файла, нет памяти, нет связи -- имхо, это не те случаи, когда нужно поднимать исключение. Это стандартная возможная ситуация. Откладывание "на потом" логики такого кода означает лишь желание (в лучшем случае) обойти конкурента, в худшем -- целенаправленно поставить в зависимость пользователя.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 09 Август, 2017 05:33 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
PSV100 писал(а):
Т.е., и лишь во время исполнения, если была ошибка открытия файла, программа вылетит в "квалифицированный assert" при ObxAscii.Eot (предполагаю, что всё-таки здесь не возвращается false при кривом аргументе, ну ли при ObxAscii.ReadChar).
Оно трапнется где-то внутри при обращении к нулевому указателю t. Ну то есть, по уму тут надо было проверить t перед использованием. "Но зачем? всё равно где-то что-то сработает! Это же Оберон, ведь не может не сработать" )))
PSV100 писал(а):
(чтобы в конечном итоге сработали хрен знает где хотя бы assert-ы в базовом языковом API, которыми пронизаны потроха основных средств платформы, насколько я понимаю.

Так и происходит, именно что "хрен знает где". Я вот на днях искал ошибки в программах - компилятор "трапался" и было уже не понятно, где же в исходнике ошибка, так как проблема обнаруживалась уже при генерации машинного кода и никаких связей с исходным кодом уже не было. Хотя, уже на уровне семантической проверки, было ясно - тут проблема и нужно сигналить. Но зачем?? Это же Оберон! Где-нибудь что-нибудь сработает! Ведь не может не сработать!


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 09 Август, 2017 17:31 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
PSV100 писал(а):
но я не в курсе, м.б. assert-ы не "отключаются" в Оберонах вообще "для надёжности", но тогда непонятна ситуация -- зачем двойная работа: "прикладные" проверки и неотключаемый анализ в assert

prospero78 писал(а):
ASSERT отключать можно. Но смысла нет, пока программа не отлажена. А в ряде случаев -- вообще не надо отключать. Сокрытие ошибки может стоить очень дорого. Что касается машинных затрат, тут вообще такими вещами можно пренебречь.

Есть паттерн организации работы процессов, в литературе обзывается аля "two path speculations". Требуется в зависимости от результата проверки выполнить один из двух процессов (или из n процессов в общем случае). Но чтобы вложиться во временные рамки вынуждены все три процесса выполнить параллельно (истинно асинхронно, и ессно подразумевается отсутствие зависимости по данным между процессами). И затем по результатам проверочного процесса используют итоги одного из прикладных процессов (если есть потребность и возможность, то прибивают другой, если он ещё не завершился).
Это пример того, что не всегда можно игнорировать машинные затраты (причём в данном случае путём ещё больше машинных ресурсов). Надёжность, которой здесь как-то можно "прикрыться" в оправдании неотключаемых assert-ов -- это совсем другая опера. Здесь аля "Segmentation Fault" -- и привет, приехали. А надёжность -- это, к примеру, ещё один паттерн вида "duplicate-transaction": запуск несколько дублирующих экземпляров процесса (возможно целенаправленно с разными алгоритмами, или/и на разных исполнителях) и последующий консенсус -- верный результат должен быть подтверждён хотя бы двумя из трёх процессов.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 09 Август, 2017 17:39 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
Kemet писал(а):
Оно трапнется где-то внутри при обращении к нулевому указателю t. Ну то есть, по уму тут надо было проверить t перед использованием.

В том и дело, что язык/платформа как-то должны способствовать быть по уму.
prospero78 писал(а):
ASSERT -- это гарантия того, что параметр подлежащий контролю ведёт себя адекватно. Чем их больше, тем проще отлавливаются баги. Но Оберон не требует их использования. Программист, если считает себя богом -- ради того же самого бога -- может жрать кактусы килограммами.

Так я о том и речь веду, что Оберон ничего не требует и вынуждает быть богом с наградой в виде кактусов.

Я не придираюсь к Оберону. Тема ошибок/исключений важна и тяжела, и пока не попадалось на глаза готовое условно идеальное решение ни на одной платформе (из рассмотренных каким-то образом в своей практике). Тем более в условиях некоего разумного минимализма. И не для флейма ради, а для вполне практичных нужд хотелось бы понять обероновский state-of-the-art.

По ходу дела вспоминается тема про Оберон-парадигму:
viewtopic.php?f=6&t=5267

где в рамках культа "гарантоспособности":
Илья Ермаков писал(а):
...
Я бы выделил для выяснения места Оберона в ИТ-экосистеме другие 3 оси:

Простота - жёсткость - расширяемость.

Жёсткость - в смысле возможности создать статически проверяемый "каркас жёсткости" для программы. Как приятное следствие - возможность разрабатывать "почти готовое ПО" без обильного покрытия тестами каждого мелкого кубика.
...
Таким образом, имеет смысл вообще исключить из языка всё, сколь-нибудь ориентированное на прикладную специфику. А оставить языку 3 функции: 1) классно абстрагировать от физической машины, при этом оставляя полную прозрачность в отображении на императивный вычислитель; 2) давать "рёбра жёсткости" - средства статического контроля, позволяющие отсеять процентов 80 наиболее досаждающих ошибок, не гоняясь за каждой остальной мелочью, коих туча разных. Не нужно думать, что от контроля прикладной семантики мы отказываемся. Всегда есть возможность заложить уже свои рёбра жёсткости в фреймворках, чтобы уже защитить себя от каких-то нарушений прикладной семантики. 3) Давать средства расширения (полиморфизм и динамическое связывание), пригодных для безболезненного включения в систему компонентов, неизвестных на этапе её создания...

И вот непонятно, как же строятся "рёбра жёсткости", да и ещё с возможностью полиморфизма, при этом "без обильного покрытия тестами каждого мелкого кубика".

Поясню свою позицию.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 09 Август, 2017 17:46 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
Я не понимаю, в чём суть "квалифицированных" assert-ов. С учётом замечания от Kemet выше ("оно трапнется где-то внутри при обращении к нулевому указателю t") и следующих результатов из этой темы:
viewtopic.php?f=82&t=6088
Kemet AND prospero78 писал(а):
Я тут глянул Report The Programming Language Oberon (Revision 1. 10. 90) и не нашел там ASSERT, только старый добрый HALT
...
Угу. Нету. Ассерт это процедура, которая пишется за одну секунду.
Проблема то в чём?
=Ссылочки давайте адекватные, плиз=
А вот тут есть. Страничка 3, будьте добры. В стандартных процедурах, как раз :lol:
Видимо, важный элемент языка для Николая Вальтеровича. И я почему-то с ним согласен))
...
Ссылку я дал боле чем адекватную - Виртовский православный Оберон, в котором нет ASSERTа.
Получается ASSERT это не Вирт-Вэй, ога.
Это я к тому, что пихать ваши любимые ASSERTы куда ни попадя не стоит. Кстати, а кто считал, сколько ASSERTов поставил Вирт в новом проекте Оберон? Похоже, они там должны быть, как минимум, в каждой процедуре, раз это Вирт-Вэй!! А вот я счас проверю, хммм, что-то я их не вижу ((( Неужто Вирт нарушил свой же Вирт-Вэй???
...
Кемет, а ту ссылочку, что я дал -- это поделка студентов?
...
Так нет ASSERTов в новейшем Project Oberon от Вирта. Не ставит.
...
Я правильно понимаю,что Oberon-07 это старьё?))

есть подозрение, что всё-таки assert-ов нет в базовом языковом ядре. Т.е. есть "трапание" SEGFAULT-а и, видимо, выдача аля "память не может быть read" (и разбирайся, к примеру, к какому это аргументу функции относится и пр.).

Предположим, что пусть assert-ы есть везде и квалифицированно выдают "у вас тут дескриптор файла не очень как-то, разберитесь...". Однако, несмотря на всю их возможную красоту -- они есть "паника", которую необходимо вычищать.
В отсутствие "классических" исключений, фактически, основной вариант: "по уму тут надо было проверить t перед использованием". Ну как заставить не забыть это сделать? Без гарантий со стороны компилятора -- это уровень гарантий как, например, в Дракон-е -- был (видимо, и есть) популярный тезис на здешних форумах: алгоритм в эргономичном виде -- "надёжный" алгоритм. Возможны какие-то дополнительные тулзы для мощного семантического анализа кода. Но, прежде всего, типы данных (и операций) должны прямо указывать на семантику вычислений. Т.е. предметные прикладные данные должны быть каким-то образом упрятаны в контейнер, их извлечение принудит к проверке (или как в аля Lustre -- компилятор понимает наличие/отсутствие данных и просто так не позволит обратится к ним). Однако, для каких-то удобных и универсальных "check"-ов в Оберон-е нет "дженериков" в каком-то виде, что позволило бы строить обобщённый код, а главное -- типобезопасный. Насколько я понимаю, единственный путь универсальности -- техника глобального "object"-типа как в "классическом" ООП: что-то вроде завести глобальный тип-record аля "Object", от него "наследоваться" остальным типам. И через "pointer" как-то заниматься тестированием и преобразованием к нужному типу. Пусть подобная техника возможна, и даже runtime-затратами можно пренебречь. Но здесь такая же "классическая" проблема как и в "классическом" ООП -- это именно runtime-решение: на этапе компиляции платформа пропустит условно любую семантику -- запросто можно смешать котлеты с мухами. В универсальный алгоритм запросто может прилететь объект, для которого не пройдут runtime-тесты и преобразования -- здравствуй снова SEGFAULT.

Конечно же, "рёбра жёсткости" в некоторых важных прикладных типах реализуются (имеется ввиду конкретные предметные типы), внедряются какие-нибудь check-и, и как-то можно заставить их не игнорировать. Но в целом, например, я не могу прочувствовать какой-то типовой сценарий обработки возможного nil при new. Складывается впечатление, что весь state-of-the-art -- SEGFAULT. В таком случае, тогда возникает вопрос -- а лучше ли без классических исключений при отсутствии альтернативы?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 09 Август, 2017 19:49 

Зарегистрирован: Вторник, 26 Январь, 2010 09:31
Сообщения: 717
Откуда: Барнаул
PSV100 писал(а):
есть подозрение, что всё-таки assert-ов нет в базовом языковом ядре. Т.е. есть "трапание" SEGFAULT-а и, видимо, выдача аля "память не может быть read" (и разбирайся, к примеру, к какому это аргументу функции относится и пр.).

В первоначальном Виртовском Обероне-1 ASSERTа нет, в текущей ревизии Оберона-07 ASSERT есть. И это уже заимствования, то-есть это не "путь Вирта". "По-Вирту" Ассерт вообще лишняя сущность, ведь есть HALT и есть IF чего ещё надо??
В ядре текущего Прожект Оберон таки есть несколько ассертов. Но только в ядре. ну или то, что называется system. В остальных модулях проекта я Ассерты не нашел.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Среда, 09 Август, 2017 21:49 
Аватара пользователя

Зарегистрирован: Воскресенье, 12 Апрель, 2015 18:12
Сообщения: 1134
Откуда: СССР v2.0 rc 1
SEGFAULT -- это уже шляпа. Это означает, что программа стартовала в космос по причине нарушения типрв, либо внешнее воздействие (сбой питания, вирус и т. д.)
Квалифицированное исключение означает:
1. Точно известно где.
2. Точно известно что.
3. Это что в месте где можно прихлопнуть, пока оно не стало страшным.
Таким образом IF и HALT не могут выполнить роль ASSERT. Их действие либо совсем локально, либо совсем глобально. Вспоминаем: в компонентно-ориентированном программировании среда обеспечивает контроль и связь модулей. Именно среда реагирует на квалифицированное исключение. SEGFAULT по определению таким не является.
Изоляция от железа -- первая сильная сторона Оберонов. Сборка мусора -- второй фактор. Невозможно обойти средства контроля типов щтатными средствами -- третий фактор и наше всё.
Не представляю себе ситуацию, когда в ходе работы Оберон-системы вылезло бы сообщение:"Программа выполнила недопустимую операцию и будет закрыта".
То, что программист, считая себя умным не контролирует ход изнутри -- признак зазнайства.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 10 Август, 2017 16:52 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
Kemet писал(а):
В первоначальном Виртовском Обероне-1 ASSERTа нет, в текущей ревизии Оберона-07 ASSERT есть. И это уже заимствования, то-есть это не "путь Вирта". "По-Вирту" Ассерт вообще лишняя сущность, ведь есть HALT и есть IF чего ещё надо??

Я в "репорте об Оберон-е 07" по ссылке в той теме ASSERT вижу, но нет HALT. Видимо, теперь HALT лишний. Непонятно, как делать аварийный выход вместо HALT(n), типа как-то так что ли: "ASSERT(FALSE, n)"?
Здесь ведь и семантика не та подразумевается, и assert-ы ведь выключить можно. Или же подразумевается, что никаких альтернативных выходов быть не должно. Видимо, понятие "структурности" алгоритмов имеет весомое место. Здесь на форуме полно соответствующих дискуссий, включая и исходную тему форума, откуда возникла текущая. Не приветствуются (а то и не допускаются) множественные выходы из циклов, из процедур, "return" только в конце процедуры и т.д. (дискуссии, мягко говоря, странные..., на фоне глобальных переменных...).


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Четверг, 10 Август, 2017 17:06 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
prospero78 писал(а):
SEGFAULT -- это уже шляпа. Это означает, что программа стартовала в космос по причине нарушения типрв, либо внешнее воздействие (сбой питания, вирус и т. д.)
Квалифицированное исключение означает:
1. Точно известно где.
2. Точно известно что.
3. Это что в месте где можно прихлопнуть, пока оно не стало страшным.
Таким образом IF и HALT не могут выполнить роль ASSERT. Их действие либо совсем локально, либо совсем глобально.
...
Не представляю себе ситуацию, когда в ходе работы Оберон-системы вылезло бы сообщение:"Программа выполнила недопустимую операцию и будет закрыта"...

Технических нюансов не знаю, и не в курсе, чем HALT от ASSERT отличается согласно какому-то критерию локальности/глобальности. Возможно ASSERT более "квалифицирован", и, скажем, согласно примеру выше про работу с файлом, при исполнении "ObxAscii.Eot(t)" программа "трапнится" не с кодом "доступ к памяти по nil" и всё, а конкретнее: "переменная t -- nil, что привело к таким-то последствиям" (что уже проще, если где-то аргументов/переменных не одна штука), при потребности выдаст точные координаты в исходнике, стек-трейс, watch-list (значение переменных и выражений), дамп памяти и пр. Но по сути это всё не важно, идеологической разницы нет.

Уточню. Я не имею ввиду крах runtime-среды Оберон-а как таковой (т.е., воспользуюсь метафорой -- вылет всей условно Оберон-машины). Под SEGFAULT и "паникой" выше здесь в теме подразумевался типовой универсальный технологический патерн: при ASSERT и прочих сигналах прерывания выполняется аварийный останов процесса и его уничтожение (вместе с его некорректным состоянием). В остальном -- конкретные платформенные нюансы, второстепенные в данном случае: сопутствующие задачи для перезапуска программ/процессов, использование IDE при разработке (в т.ч. после правки переменных/кода -- возобновление приостановленного (а не удаленного) процесса). Возможный какой-то глобальный trap-обработчик -- игнорируем, считаем его как вспомогательное техническое средство.
Т.е. ключевое -- останов и уничтожение процесса -- "паника" (с последующей диагностикой).
prospero78 писал(а):
3. Это что в месте где можно прихлопнуть, пока оно не стало страшным.

Нет, конечно же. Вылет по ASSERT и прочим runtime-проверкам в ядре -- это совсем не то место, где можно что-то прихлопнуть. То, что в Оберон-парадигме определено как "контрактно-ориентированное программирование":
Илья Ермаков писал(а):
...
Самый нижний уровень - на систему уверенно можно положиться. При возникновении остаточных проблем (которые не убраны, допустим, ввиду не проводившегося серьёзного тестирования) за счёт хорошей структуры ПО и контрактно-ориентированного программирования они устраняются разработчиком моментально
...

означает выявление проблем постфактум -- в этом месте уже ничего сделать нельзя, кроме как "стартовать в космос". И "моментальные" устранения -- далеко не общий случай.
В том же С++ не возникает какого-то идеологического ступора -- мол, зачем исключения, когда ASSERT есть.
prospero78 писал(а):
Невозможно обойти средства контроля типов щтатными средствами -- третий фактор и наше всё.

Так проблемы не в том, что не обойдёшь runtime-контроль типа. Если в процедуру, принимающую какой-то универсальный тип Object, прилетит "мусор" (что позволит компилятор) -- надёжная runtime-среда выдаст "квалифицированный полёт в космос" -- а толку то? (вновь разработчик вынужден "устранять моментально").
prospero78 писал(а):
То, что программист, считая себя умным не контролирует ход изнутри -- признак зазнайства.

Именно такие впечатления и есть: Оберон-программист не должен зазнаваться, на него полностью, от и до, возложили "самый настоящий технический долг".


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 15 Август, 2017 20:04 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
На форуме обнаружилась аналогичная тема, также прошлых лет:
viewtopic.php?f=26&t=808

Выделю ключевое:
viewtopic.php?f=26&t=808#p11949
Илья Ермаков писал(а):
Vlad писал(а):
И если в языке делать это обработку непросто (проводится политика "нам это не нужно, потому что у нас есть коды возвратов, а если коды для вас не модно, то извращайтесь с ООП разъемами"), то на практике это приводит к тому, что ошибки или не обрабатываются (игнорируются) или обрабатываются "на отвяжись" (в лучшем случае возвращается невнятный код ошибки).

И Вы тоже не поняли мысли... Саму тему Geniepro начал отсюда: viewtopic.php?p=11906#p11906 - там упоминалось мнение Бертрана Мейера по поводу обработки исключений.
Ошибки, про которые Вы говорите (при взаимодействии с внешней средой) - это пока ещё НЕ ИСКЛЮЧЕНИЯ. Не исключения до тех пор, пока их можно делегировать на верхний уровень. Т.е. пока это ожидаемо. И здесь лучше коды ошибок.

Речь идёт о ситуации, когда делегировать выше мы не можем - потому что наша служба имеет высокоуровневый интерфейс, который имеет контракт (пред-постусловия) более сильный, чем можно обеспечить на базе слоя, лежащего ниже. Например, мы дали выше абстракцию абсолютно надёжной связи, а ниже-то лежит сеть, из которой узел может в любой момент пропасть... И вот это уже действительно исключение, потому что связано с нарушением контракта. И нужно эту разницу в контрактах компенсировать. Только делегация вверх по стеку в таких ситуациях часто бессмысленна, особенно в параллельных приложениях. Так что try-catch оказывается бесполезен. А выручают "разъёмы". Так на кой мне в языке тот механизм, который в единственном реально нужном и важном случае не позволяет организовать обработку НАСТОЯЩИХ исключений? (а не багов, кои должны обрабатываться ASSERT + библиотечной try-обёрткой где-то на уровне главного цикла сообщений приложения, и не предусмотренных ошибок, которые делегируются всегда точно на уровень вверх и для которых ничего лучше кодов ошибок не придумано...)

Для полноты картины приведу здесь цитату из источника дискуссии:
viewtopic.php?p=11906#p11906
merk писал(а):
...
полезность исключительных ситуаций формально постулируется так. не помню автора, возможно майер(если не ошибаюсь), автор Эйфеля.
исключительная ситауция должна возникнуть тогда, когда функция проверив на корректность предусловия, не может своим кодом выполнить постусловия. Все остальное от лукавого. То есть с точки зрения теории, выход из функции заперт невыполнимыми постусловиями. тогда необходима иная форма выхода - что и есть генерирование искл. ситуации.
Любовь к исключениям просто для передачи результата навроде - хотели файл открыть а его нету! это вульгарное использование механизма исключений, порождающее споры с мордобоем, зачем они вообще.
Исходя из определения видно, что если вы ослабите постусловия функций, вы теоретически можете сократить необходимость исключений до нуля - при постусловиях, что любая постситуация не нарушает корректности функции.
то есть спор - нужно-не нужно абстрактен. зависит от того, какими вы видите постусловия ваших функций. лично я исключения стараюсь не использовать вообще, если это в моей власти.

Да уж, споры "с мордобоем" не утихают до сих пор. Напомню, от чего "ожила" эта тема форума:
viewtopic.php?f=6&t=1454&start=40#p101429
prospero78 писал(а):
Мадзи писал(а):
Если входные данные проверяются перед обработкой на допустимость, а также существует проверка выходных данных, то исключительным ситуациям взяться просто неоткуда.

Ос, сенсей!

А далее были небольшие прения, что же есть именно исключительная ситуация. Теперь, согласно цитате выше, можно опереться на авторитет Бертрана Мейера. Итак, исключение возникает тогда, когда функция с корректным предусловием не может выполнить постусловие. Причём определение допускает некоторые теоретические манипуляции. Напр., исключительную ситуацию понимать как сбой, отказ -- "fail", а выявление некорректности предусловия -- паника -- "panic". А может наоборот, пусть здесь теоретики предложат истину. Я же попытаюсь акцентировать на проблематике, которая возникает вокруг "вульгарного" использования исключений, т.е. тогда, когда предполагается прикладная алгоритмическая реакция на неуспех операций. Следует отметить, что нет никакой "коллизии в теории", к примеру, в рамках операции доступа к элементу контейнера по индексу аля "a[...]", где гарантируется успех в случае корректного предусловия, и при допустимом предусловии может возникнуть лишь технические проблемы (напр., сбой оборудования). Поэтому здесь возникает (целенаправленно согласно идеологическим принципам в семантике организации вычислений в данном случае) потребность не в реакции на неуспех, а в алгоритмической гарантии предусловия.

А вот исторически сложившеюся практику "вульгарности" использования исключений раскрывает документ из той смежной темы форума: "Zero-Overhead Exception Handling Using Metaprogramming", реализация обработчиков исключений в виде спец-процедур для Оберона:
viewtopic.php?f=26&t=808#p11933

Исходная ссылка на документ не работает, имеется, напр., здесь:
https://www.semanticscholar.org/paper/Z ... 1a86e9cba0

Там неплохо обобщена суть обработки исключений. Основная выгода отделения реакции на проблемы от основного алгоритма:
Цитата:
...
Exception handling is the ability to separate the reaction to a program failure (i.e., to an exception)
from the place where the failure occured. This has two advantages:
• It keeps algorithms free of error handling code.
• It allows a programmer to implement the reaction to different occurrences of the same exception in
a single place.
...

Основные принципы реакции на неудачу:
Цитата:
General principles. Exception handling is built around three concepts: a block of statements that is
protected against exceptions; one or more exception handlers that are specified for the protected
block; and a mechanism to raise exceptions. If an exception is raised during the excution of the
protected block, the corresponding handler is executed. Some exceptions can also be raised by the
system because of illegal operations (e.g. division by zero). After the exception was handled the
program can be continued in one of three ways:
• Terminate semantics: The protected block is terminated and the program continues with the first
statement after the block.
• Resume semantics: The execution of the protected block is resumed after the point where the
exception was raised.
• Retry semantics: The protected block is re-executed from the beginning (after the exception
handler has repaired some conditions which caused the block to fail in the first try).

Many languages support only terminate semantics...

Действительно, в большинстве случаев в языках имеется лишь "terminate semantics". Ранее здесь были примеры прочих подходов ("Conditions and Restarts", "continuations", в данной статье рассматриваются Eiffel, Smalltalk, а также продемонстрирована resume-семантика в представленной технике обработки исключений).
Причём явление "terminate semantics", видимо, необходимо понимать широко. Не всегда возможен выход из процесса как таковой. К примеру, актор (исполнитель как процесс, автомат) может завершить очередной такт своей работы и остаться в системе (не завершён, не выгружен) вместе со своим состоянием (в т.ч. возможен перевод объекта в специализированное состояние -- изменение поведения).

Здесь в теме были попытки обобщённо взглянуть на проблематику механизма исключений и придать ему "особый статус":
Руслан Богатырев писал(а):
Исключения (exceptions) -- это особый механизм, которым просто так пренебрегать не стоит. При работе с аппаратурой известны два режима: (1) работа по готовности и (2) работа по прерыванию. Исключение можно рассматривать как программное прерывание. Исключение имеет плюсы и минусы, схожие с плюсами и минусами при работе по аппаратным прерываниям. Для начального обучения программированию, думаю, изучать исключения не стоит. Да и во многих прикладных проектах они могут принести больше вреда, нежели пользы. Вот если касаться системного ПО -- это совсем другое дело.

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

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

Но надо понимать, что исключения еще более опасны, чем goto. Они могут приводить к таким наведенным эффектам, которые локализовать и нейтрализовать бывает крайне трудно. ASSERT в Обероне -- это компромисс. Это упрощенные исключения, позволяющие не потерять контроль над "сигнальной шиной". При желании можно, оставаясь в терминах ASSERT, обеспечить в языке полноценную обработку исключений. Но цена за это -- опасность возникновения ошибок иного рода и наведенных эффектов, вызванных самими исключениями.

Кстати, насчёт ASSERT. Фактически, этот механизм есть некие упрощённые исключения, и здесь в его адрес уместна основная критика блоков try-catch. Как к примеру:
Madzi писал(а):
Alexey_Donskoy писал(а):
В системах 24х7 оба примера никуда не годятся :)
Давайте уж сравнивать сравнимые вещи. Например:

Вариант 1: try a:=x/y except a:=inf end;
Вариант 2: if abs(y)>=eps then a:=x/y else a:=inf;

Или же:
Вариант 1: try a:=x/y except {значение а не изменяется} end;
Вариант 2: if abs(y)>=eps then a:=x/y;

По-моему, так эти варианты ничего по существу не доказывают. Их использование зависит от задачи. Удобство не сильно отличается. Затраты, в общем, тоже не сильно.

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

Точно также, оставленные assert-ы в "продакшине" ни разу не означают "надёжность". Оправданием может быть лишь прагматика (дополнительное тестирование затруднительно или пока ещё не проведено, верификация проблематична или невозможна, требуется значительное увеличение стоимости или/и временных затрат и пр.).

К характеристике механизма исключений/ошибок стоит ещё добавить следующее полезное свойство (из смежной темы про исключения):
viewtopic.php?f=26&t=808&start=80#p68382
Сергей Прохоренко писал(а):
...
Но, в отличие от оператора Exit (отсутствующего в PureBuilder), оператор Escape():

объявляет сигнал отказа – переменную логического типа – и присваивает ей значение «истина»,

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

Вся возможная семантика исключений там не рассматривалась, но важное -- "скомпрометированность" данных (а далее в той теме форума наблюдается "затык" с глобальными объектами в программах, но это второй вопрос). Популярные try-блоки "классических" исключений, несмотря на их зафиксированные здесь недостатки, "скомпрометированность" данных обеспечивают (прерывание процесса, которое к тому же не проигнорируешь, не позволяет воспользоваться некорректными данными). Однако, ограниченно в общем случае. Например:
Код:
var a: ...
var b: ...
...
try
  a = A();
  b = B();
catch
  ...
end;
C(a);
D(b);
...

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 15 Август, 2017 20:16 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
Итого. Прежде всего, нельзя сказать, какой именно способ обработки ожидаемого неуспеха операций единственно верный. В случаях прямого анализа кодов ошибок "по месту" имеем "структурный" обработчик, что поближе к "структурности" алгоритмизации в целом. Однако, в ряде случаев алгоритм может существенно усложниться из-за наличия множественных проверок, к тому же не редко возникают сопутствующие задачи "откатов" изменений, освобождения ресурсов и др. (причём какой бы алгоритмической техникой не воспользовались бы, даже с учётом механизмов автоматического исполнения деструкторов/финализаторов, всё равно ситуация тяжелее, чем представление задачи в виде "happy path"). И отделение реакции на неуспех от основного предметного алгоритма не лишено существенных оснований. Фактически, как было отмечено в цитатах, можем выделить условную "сигнальную шину". Где, однако, в общем случае осуществляется не только делегация проблем в выше стоящие инстанции (условно наверх по стеку), но возможно взаимодействие с произвольными подсистемами (вертикально и горизонтально со смежными акторами/автоматами). Причём именно взаимодействие -- разная семантика (кроме останова -- возобновление и повтор операций, или же альтернативный путь алгоритма). Поэтому, фактически, язык/среда должна обеспечивать контролируемую возможность реализации как структурных, так и неструктурных обработчиков сигналов о неудачах.

Очевидно, что классические блоки try-catch выполняют лишь часть функций, и в полной мере не реализуют "сигнальную шину". В отрасли в последние времена наблюдается тенденция неприменения механизма классических исключений, тем самым снимания вопрос "вульгарности". Появляются средства для облегчения реализации структурных обработчиков неуспешных результатов. В том же Rust, здесь неоднократно задетому, подражают "функциональщине", используя "виртуальные" монады, а в дополнение операторы "?" с "try-catch" -- как синтаксический сахар для установки результата функции и досрочного выхода. В Swift-е от Apple заметны такие помогалки как оператор "guard". И в сфере "функциональщины" можем найти идентичные средства "terminate-семантики" (ну и "упаковку" результатов в алгебраические типы для "скомпрометированности" само собой). Напр., модификация do-блоков как в Idris, где альтернативы "по месту" в сопоставлении с образцом предназначены для досрочного возврата значения функции и выхода:
Код:
emain = do [prog, arg] <- getArgs | [] => putStrLn "Can't happen!"
                                  | [prog] => putStrLn "No arguments!"
                                  | _ => putStrLn "Too many arguments!"
           putStrLn $ "Argument is " ++ arg
           {- ... rest of function ... -}

Или "let-before" в Clean (где нет do-нотации в стиле Haskell), вместо:
Код:
readchars :: *File -> ([Char], *File)
readchars file
| not ok     = ([],file1)
| otherwise  = ([char:chars], file2)
where
    (ok,char,file1)   = freadc file
    (chars,file2)     = readchars file1

удобнее через упреждающий "let" -- оператор "#" (плюс "|" для защитных выражений):
Код:
readchars :: *File -> ([Char], *File)
readchars file
#   (ok,char,file)    = freadc file
|   not ok            = ([],file)
#   (chars,file)      = readchars file
=   ([char:chars], file)

Однако, подобные техники направлены лишь на поддержку "terminate"-семантики алгоритма. Вопрос с остальными принципами обработки ошибок никуда не пропадает. Видимо (т.е. неизбежно), здесь для организации "сигнальной шины" должны использоваться прочие языковые и библиотечные средства (взаимодействие процессов в том или ином виде -- обмен сообщениями, акторы, автоматы, аля "go-функции" и прочие фирменные фишки). Часто аргументацией неиспользования механизма исключений выступает критика "неструктурности" обработчиков, мол не виден весь алгоритм, может быть прерван в любой момент и пр. Здесь выше этот момент рассмотрен, и эта проблематика не так проста, чтобы её полностью игнорировать или ликвидировать.

Видимо, в условном идеале необходим компромисс, баланс средств. В смежной теме про исключения по этому поводу отлично выразился уважаемый Alexus (А. Усов), почти по Эшби:
viewtopic.php?f=26&t=808&start=140#p68703
alexus писал(а):
Сергей Прохоренко писал(а):
Минимизация языка программирования – тоже не панацея. Для программирования высокоуровневых конструкций на минимальном языке придется использовать изощренные приемы и писать много кода.

Попробую поделится наблюдениями... Если взять всего две базовых конструкции: присваивание и сравнение (как частный случай арифметики), то этого вполне достаточно для написания программ... но трудоёмко. Чтобы снизить трудозатраты, дадим возможность создавать и поименовывать комплексы/агрегаты из этих двух конструкций - макроопределения. Трудозатраты снизятся примерно в 1000 раз при росте многообразия примерно в 100 раз. Введём правила создания макросов, например, правила структурного программирования (описание и построение минимального количества оптимальных/универсальных комплексов)... трудозатраты на разработку программ снизятся ещё в 10...100 раз, а многообразие уменьшится примерно в те же 10...100 раз.
Вообще, вопрос минимизации количества типов элементов является очень интересным с точки зрения семантики систем. И любая(!) большая система (более 4-х уровней), образует ромб, где повышение многообразия сменяется его уменьшением... и всё это происходит не случайно, а вполне закономерно...


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Вторник, 15 Август, 2017 20:33 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
PSV100 писал(а):
В рамках "Оберон-подхода" (назову это так) напрасно игнорируется подход управления "от данных", как здесь:

prospero78 писал(а):
Оберон не игнорирует такой подход)) Подход "от данных" просто перпендекулярен Оберон-технологии.
Данные пассивны. Как бы не требовался динамизм в системе, лично я -- против, чтобы данные управляли программой (разумеется в проблеме лексического анализа текст управляет ходом программы, но это из другой оперы).

Вспомнилось к случаю..., если игнорировать управление "от данных", то в итоге они встанут именно что перпендикулярно "классической структурности" алгоритмов, как в этом случае :) :
http://forum.drakon.su/viewtopic.php?f= ... =40#p61677

В общем, тамошний dataflow с автоматами -- как раз очень таки компромисс, о котором речь выше. Причём акцент на принципах той школы 80-х годов, а не на современных "пародиях". Так называемый "Functional Reactive Programming" в функциональных языках, фреймворки аля семейство ReactiveX, Akka Streams, Intel TBB и прочие "Reactive Manifesto" направлены именно что на реализацию потоковых вычислений в виде построения явного вычислительного графа узлов (что поближе к функционалу StreamIt, SigmaC и пр.). А аля Scala.React предполагают лишь "мгновенную" реакцию на сигнал (и то, без спец-плагина для компилятора никак), не рассматривая прочий Esterel-функционал (без которого смысла в "реактивности", мягко говоря, очень мало).

Прежде всего, управление от данных, как таковое, означает жёсткий контроль "скомпрометированности" данных. Тамошние функции имеют понятие наличия/отсутствия данных при каждом исполнении. К примеру, декларация типа функции открытия файла могла бы выглядеть примерно так (упрощённо, псевдокод по мотивам):
Код:
fn file_open: (name: str) -> (f: file, e: int)
fn file_open:: a -> (b, c) where a > b and a > c and b <> c

где второе объявление через "::" -- указание "clock"-ов (тактов) для данных -- переменные определяют наличие данных. Здесь "a" вырождается в главную частоту функции, т.е. этот конкретный входной аргумент имеется всегда при исполнении функции. Такты результатов функции есть подмножество, и они не совпадают (или дескриптор файла, или код ошибки). Такие "сложности" оправданы для всякого разного функционала, особенно с более навороченной алгоритмической семантикой (плюс имеется широкий набор операций для явного учёта тактов для специфических задач). Но clock-и выявляются в большинстве случаев автоматом как часть вывода типа. А в простых случаях возможно и проще аля:
Код:
fn file_open(name: str) = (f: file / e: int)

И компилятор всегда анализирует доступ. К примеру, код в виде уравнений (или "патернов" в терминах ML-подобных языков) аля:
Код:
fn some_oper(fname: str) = (c: char / e: int) where
  rec f, e = file_open(fname)
  and c = read_char(f);

где второе уравнение будет вычислено только при возникновении "f". Компилятор всегда потребует явной проверки в каком-то виде в случаях непоняток, возможно так:
Код:
fn some_oper(fname: str) = (c: char / e: int) where
  rec fhandle, err = file_open(fname)
  and present
      | fhandle(f) => c = read_char(f)
      | err(n) => e = n;
      end;

Существуют разные стили проверок (для функций как "автоматы с состоянием" предусмотрен расширенный контроль, где данные анализируются для каждого такта автомата, имеются операторы в стиле "last <переменная>" -- взять последнее определенное значение, полученное когда-либо и пр.). Фактически, наблюдается неявная обвёртка данных в виде алгебраического типа в стиле "Option[x] = Some(x) | None". Такое упрощение имеет и техническое преимущество. К примеру, здесь нет явных каких-то флагов и прочих runtime техник определения тега типа-перечисления, впрочем возможны при потребности. Здесь техника аля отслеживания инициализации переменных, но расширенная. И в случаях декларативного построения кода возможны глобальные перестройки вычислений (развёртка всех деклараций, условно привязка к единому "if"-у и пр.). Явные алгебраические типы также на борту к услугам. В т.ч. для вариативных данных используется явный спец-тип вида "signal" или "sig", как здесь:
Код:
val f: file;
val c: char;
val err: signal[int];

...
par/or do
    f, emit err = file_open('file.dat');
    c = read_char(f);
with
    val e = await err;
    print('error: ' + e);
done
...

где фрагмент какой-то функции с par-блоком -- два "конкурентных" или параллельных процесса (но не истинно параллельных или асинхронных). Упрощённо -- как оператор "select" в Go (но очень приблизительно). Семантика блока задана как "or" -- весь блок завершится по окончании работы любого из процессов. Здесь при операторе "эмиссии" сигнала (emit) произойдёт переключение контекста -- на await в другом процессе, который завершится обработкой ошибки и "вытеснением" всего параллельного блока. В таком стиле организуются "неструктурные" обработчики неудач.

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

В общем, в тех краях не Scala c "реактивностью", там совсем другое понятие "потока данных".


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 18 Август, 2017 14:31 

Зарегистрирован: Пятница, 20 Июль, 2007 17:26
Сообщения: 710
Откуда: Псков
Обработчик ошибок и уязвимость, свежий пример.
http://citforum.ru/news/37788/


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Суббота, 19 Август, 2017 16:44 

Зарегистрирован: Понедельник, 25 Июнь, 2012 17:26
Сообщения: 473
Всё-таки, в случае с CAN проблема вне языковой среды (или реализации) и не зависит от способа обработки ошибок -- структурный или нет обработчик. Здесь проблематика в самой модели системы (и вероятно, что в 80-х гг. при внедрении стандарта спецификации отвечали требованиям промышленности тех лет).

Кстати, в отрасли проявляются попытки применения языков программирования для моделирования ответственных протоколов взаимодействия. К примеру -- проект F-Star:
https://fstar-lang.org/

где техники верификации (кроме базовых как "зависимые типы") адаптируются как раз для задач криптографии и прочего security (видимо, и в CAN какое-то развитие не обойдётся без элементов защиты, или в рамках дополнительных высокоуровневых протоколов). В F-Star подход на основе монад (принципы иные по сравнению с различными популярными технологиями проверки моделей взаимодействующих процессов/автоматов, как напр. в Spin/Promela), затачиваемый под определенные потребности задач, к примеру ("secure multi-party computation"):
https://www.cs.umd.edu/~aseem/wysstar.pdf


А вот гораздо "веселее", когда есть условно правильный обработчик ошибок, а вот уязвимость и прочие глобальные проблемы -- именно из-за языковой среды. Яркий пример (точнее, здесь недостаточный контроль со стороны языковой платформы):
http://rsdn.org/forum/cpp/5654034.all

и в той дискуссии приведен ещё подобный глюк: http://goo.gl/1x6VjQ

Здесь из-за благих целей оптимизации "переполнение" возникает ещё во время compile-time, в итоге -- "undefined behavior", и в run-time в результате -- "форматирование" диска.

Выше в теме форума были перечислены критерии надёжности языковой парадигмы (в частности Оберона). Видимо, даже не на первом, а на нулевом месте должна быть надёжность семантики языка, прежде всего.


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 16 Ноябрь, 2018 13:28 

Зарегистрирован: Суббота, 07 Март, 2009 15:39
Сообщения: 3261
Откуда: Астрахань
Дело не в механизме обработки исключительных ситуаций.
Это просто ИНСТРУМЕНТ в языке.
Он может быть тем или другим.

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

Я вот пишу фронт-енд компилятор Семантик->Cpp.
Дык обработка исключений мне помогает очень конкретно локализовать вывод синтаксических ошибок.
Это можно сделать и без инструмента обработки исключений, но сам инструмент меня надоумил.

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 16 Ноябрь, 2018 14:40 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
Валерий Лаптев писал(а):
Я вот пишу фронт-енд компилятор Семантик->Cpp.
Дык обработка исключений мне помогает очень конкретно локализовать вывод синтаксических ошибок.
Это можно сделать и без инструмента обработки исключений, но сам инструмент меня надоумил.
Для меня это звучит довольно странно. Если обработка исключений помогает Вам локализовать вывод синтаксических ошибок, то можете прояснить, как отсутствие исключений мешает локализации?


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 16 Ноябрь, 2018 15:15 

Зарегистрирован: Суббота, 07 Март, 2009 15:39
Сообщения: 3261
Откуда: Астрахань
Comdiv писал(а):
Валерий Лаптев писал(а):
Я вот пишу фронт-енд компилятор Семантик->Cpp.
Дык обработка исключений мне помогает очень конкретно локализовать вывод синтаксических ошибок.
Это можно сделать и без инструмента обработки исключений, но сам инструмент меня надоумил.
Для меня это звучит довольно странно. Если обработка исключений помогает Вам локализовать вывод синтаксических ошибок, то можете прояснить, как отсутствие исключений мешает локализации?

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


Вернуться к началу
 Профиль  
 
СообщениеДобавлено: Пятница, 16 Ноябрь, 2018 17:20 

Зарегистрирован: Четверг, 08 Май, 2008 19:13
Сообщения: 1447
Откуда: Киев
Я исхожу из логики: если с чем-то лучше(помогает), то без него хуже(мешает отсутствие), а если дело не в инструментах, то слово "помогает" попадает в область каши из топора.


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

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


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

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


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

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