adimetrius писал(а):
Илья Ермаков писал(а):
Так он не двойной там! Он одинарный - и два IF.
О, а я не заметил! случайность ⋁ непривычность ⋁ неясность
В самом деле, "защитные выражения" цикла явно не выделяются, кроме как с помощью цветового оформления на исходной картинке, но такое решение вне языковых конструкций.
Вспоминаются попытки "обобщенного цикла" с операторами CHECK, АndWhile (операторы "верхнего уровня" в блоке-цикле, разрезающие блок на части):
*
https://forum.oberoncore.ru/viewtopic.php?p=57745#p59240*
http://oberspace.org/index.php/topic,425.msg13272.html#msg13272Однако, кроме отношения следования между "защитными выражениями" необходимы и альтернативы условий (как в "цикле Дейкстры")...
Сейчас появляется мода на явный оператор "защитного выражения". Напр., таковой ввели в Swift -- оператор guard:
https://www.programiz.com/swift-programming/guard-statementПо сути, это "if", но с пустым телом then-части, нет elsif-альтернатив, else-часть (срабатывающая, если условие не истинно) должна предусматривать выход из текущей синтаксической области. В общем, узаконенный способ для "раннего выхода", небезосновательно, однако:
*
https://blog.timoxley.com/post/47041269194/avoid-else-return-early*
https://habr.com/ru/post/348074/Структурные решения вида "return только в конце" с проверками для каждого этапа "монады" (с целью уменьшения вложенности условных блоков) аля:
*
https://forum.oberoncore.ru/viewtopic.php?f=27&t=3175#p57990*
https://forum.oberoncore.ru/viewtopic.php?f=6&t=2290всё же, подвержены лишним проверкам (возможно оптимизирующие компиляторы иногда ситуацию улучшают, да и далеко не в каждой предметке проблематика ощутима).
В "компонентном ассемблере" Недори есть аналог оператора guard как "
проверить Условие
завершить [ Выражение ]" -- стиль: "отбрось лишнее, потом работай" ("в каком-то смысле, оператор
проверить является инструментом реализации «главного маршрута алгоритма» в Дракон диаграммах"):
http://digital-economy.ru/stati/komponentnyj-assembler-chast-2-dukh-yazykaОднако, Недоря декларирует применение "проверить" лишь в начале процедуры -- "защитное выражение" всей подпрограммы. Видимо, по аналогии с циклом выше и из-за таких же потребностей, напрашивается расширение допустимой области, но только в пределах верхнего уровня процедуры, не внутри каких-либо операторов (в таком случае досрочные выходы должны быть подкреплены некими механизмами аля defer или scope exit как в D, секция finally, деструкторы или финализаторы). Вид оператора пусть будет таким:
Код:
GUARD condition ELSE
...
RETURN ...
END
Тогда для LOOP вместо EXIT также можно предусмотреть свои "защитные выражения", но в отличие от защит процедуры, оператор GUARD защищает дальнейшие, именно циклические, действия (недолжно быть "нециклических" операций, связанных с прерыванием цикла). Вместо ELSE используется DO:
Код:
LOOP GUARD c1 DO
p1;
GUARD c2 DO
p2;
ELSIF c3 DO
p3;
END
END END
В операторе GUARD DO нет ELSE, возможны ELSIF-альтернативы. Если условие ложно, цикл прерывается. После GUARD не допускается следование каких-то иных операций.
Операторы WHILE (в т.ч. и как "цикл Дейкстры"), FOR (с защитой вида "для всех ..."), фактически, по сути есть синтаксический сахар как частные случаи обобщённого цикла LOOP-GUARD.
Возможна краткая форма цикла с единственным GUARD в конце (без DO) как аналог do-while:
Код:
LOOP
...
GUARD condition END
В таком случае исключается потребность в REPEAT...UNTIL, и тогда существует единая методология для всех форм цикла.
По сравнению с исходным примером цикла в данном случае нет "ELSE EXIT" и наблюдается явное ключевое слово GUARD.
Вот такие вот защиты действий и защиты циклических операций (в общем, прям классика ...).