Позволить конструкцию вида while !( условие ) { }

Павел Ольховиков
Павел Ольховиков

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

Пример 1. Существующее решение.

Данный пример читается как "остановить цикл как только условие1 и условие2 истинны". Запись в более традиционной форме выглядела бы как:

while ( !( условие1 && условие2 ) )  {
    // тело цикла
}

Цикл прекратит выполнение, как только внутреннее условие истинно.

Пример 2. Чуть более традиционная запись.

while (  !условие1 || !условие2  )  {
    // тело цикла
}

Воспринимается это несколько труднее: "выполнять, пока условие1 или условие2 не станет ложно".

Тоже самое справедливо и для более сложных внутренних условий:

Пример 3. Сложное условие.

while ( !(условие5 || (условие1 && условие2 ) || (условие3 && условие4) ) ) { }

Читается несколько проще, чем если бы мы записали более традиционно "Выполнять пока очень_сложное_условие(см. пример ниже)"

Однако, такой подход имеет недостатки, заметные уже из примера:

  • он не достаточно нагляден;
  • появляются лишние скобки, затрудняющие восприятие выражения целиком;
  • в длинных условиях не вполне ясно, как далеко простирается отрицание.

Ввод отрицания перед условием позволил бы синтаксически подчеркнуть принцип работы цикла и облегчить его восприятие:

Пример предложенного синтаксиса:

while !(условие5 || (условие1 && условие2 ) || (условие3 && условие4) ) { }

Традиционная запись:

while ( !условие1 && (!условие2 || !условие3) && (!условие4 || !условие5 ) ) { }

Преимущества предложенного синтаксиса перед примером 3:

  • нет сомнений, что такое отрицание, идущее сразу после слова while, простирается на все условие;
  • сразу видно, что нужно читать цикл как "остановить как только условие истинно", а не "выполнять пока";
  • отсутствие лишних скобок в целом улучшает визуальное восприятие.

Преимущества перед традиционной записью:

  • мы в принципе можем записать такое условие без калькулятора логических выражений;
  • мы даже способны его прочитать, и это даже не составит труда, если условия будут короткими переменными или фунциями : )
-9
рейтинг
4 комментария
croessmah
#define until(expr) while(!(expr))

//usage:
int x = 5;
until (x == 0) {
//...
--x;
}
croessmah
Павел Ольховиков
croessmah, при принятии стандартов, во всю происходит борьба с препроцессором, а вы предлагаете такое кощунство?
Кроме того, использование слова until не в лучшую сторону влияет на восприятие кода, потому что внимание программиста заточено на поиск таких ключевых слов, как while, а я лишь предлагаю одним символом удобно менять его поведение.
Мое предложение позволяет создать удобное единое синтаксическое средство, понятное всем, использование макросов в данном случае наносит куда больше вреда, нежели вариант while(!(expr)).
Ваш вариант практически не обладает преимуществами, описанным в статье.
Павел Ольховиков
croessmah
Павел Ольховиков, while !() - намного хуже, конечно же, это моё мнение. А еще нужно будет do {} while !(). Следом будет вопрос почему нет if !(). Что касается until, то есть языки с таким кейвордом, так что те, кто знаком с подобным, поймут в чем дело. Лично мне проще видеть один вариант while - while(!(expr)).
croessmah
Павел Ольховиков
croessmah, знаете, что в нем хорошего? Его значение очевидно даже тем, кто не будет знать о возможности такой конструкции, и это практически не изменяет существующий синтаксис, разве что позволяет вынести один оператор за основные скобки, позволяя уменьшить их количество.
Павел Ольховиков
Другие идеи
Группа создана, чтобы собирать предложения к стандарту C++, организовывать их внутренние обсуждения, помогать готовить их для отправки в комитет и защищать на общих собраниях в рабочей группе по С++ Международной организации по стандартизации (ISO).