Oberon space
General Category => Общий раздел => Тема начата: ilovb от Июнь 29, 2014, 02:34:25 pm
-
Есть такая плюшка в аде (в выражениях). Еще была тема на oberoncore (искать лень), где Илья Ермаков возжелал такой механизьм для последовательности действий.
В обсчем я тут покодил на Go, прочуйствовал обработку ошибок, и задался вопросом:
А что мешает добавить ANDIF по аналогии с ELSIF?
IF cond1 THEN
ANDIF cond2 THEN
ANDIF cond3 THEN
ELSIF cond4 THEN
ANDIF cond5 THEN
ELSE
END;
ветка ANDIF выполняется тогда и только тогда, когда истинно условие предыдущей ветки (IF, ANDIF или ELSIF)
Структурно это замена вложенного IF:
IF cond1 THEN
IF cond2 THEN (* это ANDIF *)
IF cond3 THEN (* еще ANDIF *)
END;
END;
ELSE
IF cond4 THEN (* это ELSIF *)
IF cond6 THEN (* следующий ANDIF *)
END;
ELSE
IF cond5 THEN (* еще ELSIF *)
END;
END;
END;
Этот код транслируется в:
IF cond1 THEN
ANDIF cond2 THEN
ANDIF cond3 THEN
ELSEIF cond4 THEN
ANDIF cond6 THEN
ELSIF cond5 THEN
END;
Мне кажется, что это совершенно естественный сахарок как и ELSIF. Какие тут могут быть проблемы? (Укажите если кто видит)
С другой стороны можно сделать более явную конструкцию:
CHAIN cond1 :
| cond2 :
| cond3 :
END;
Смысл в том, что цепочка прерывается, как только не выполнится очередное условие.
-
Ты просто хочешь монады, но сам того не осознаешь :-)
-
Мне кажется, что это совершенно естественный сахарок как и ELSIF. Какие тут могут быть проблемы? (Укажите если кто видит)
1. В последовательности эндифов легко пропустить элсиф, поэтому читаемый код будет понят неправильно.
2. Эндиф - это не просто вложенный иф, а вложенный иф, который находится в самом конце внешнего ифа. То есть, это частный случай, который совместно с первым пунктом кажется не особо полезным.
-
1. Вот потому и спрашиваю мнения со стороны. У меня тоже есть подозрения что можно будет пропустить чего...
2. Как раз этот частный случай и нужен на практике.
Например когда выполняешь некие функции, возвращающие код ошибки.
Есть только два варианта:
1.
err := F1();
IF ~err THEN
err := F2();
IF ~err THEN
err := F3();
IF ~err THEN
F4();
END;
END;
END;
При длинной цепочке это превращается в адЪ
Можно делать иначе:
err := F1();
IF ~err THEN
err := F2();
END;
IF ~err THEN
err := F3();
END;
IF ~err THEN
F4();
END;
Так гораздо лучше, но коробит от лишних проверок.
А вот как это будет с ANDIF:
err := F1();
IF ~err THEN
err := F2();
ANDIF ~err THEN
err := F3();
ANDIF ~err THEN
F4();
END;
Линейный код без лишних проверок. И шаблон цепочки явно выражен с помощью ключевого слова ANDIF.
-
А еще у меня была мысль делать отступы для ANDIF:
IF cond1 THEN
ANDIF cond2 THEN
ANDIF cond3 THEN
ELSEIF cond4 THEN
ANDIF cond6 THEN
ELSIF cond5 THEN
END;
Так вроде невозможно запутаться.
-
Хотя нет. С отступами плохая идея.
-
Почему плохая?
Эндиф как замена вложенному ифу для конца внешнего ифа хороша до тех пор, пока не появляются ещё и ифы в середине внешнего ифа.
-
Плоха т.к. с толку будет сбивать. Пусть лучше на своем уровне.
Про "ифы в середине внешнего ифа" не понял. Можно пример?
-
IF e1 THEN
v1 := F1();
IF P(v1) THEN
v2 := F2()
END;
v3 := F3(v1, v2)
ANDIF
Fx()
END;
-
Ну и все прекрасно же.
IF e1 THEN (* первое звено *)
v1 := F1();
IF P(v1) THEN
v2 := F2()
END;
v3 := F3(v1, v2)
ANDIF e2 THEN (* второе звено *)
Fx()
END;
В том и соль, что там где нет ANDIF там и цепочки нет
-
А вот как это будет с ANDIF:
err := F1();
IF ~err THEN
err := F2();
ANDIF ~err THEN
err := F3();
ANDIF ~err THEN
F4();
END;
Линейный код без лишних проверок. И шаблон цепочки явно выражен с помощью ключевого слова ANDIF.
Плохой вариант имхо.
В операторе IF-ELSIF все условия вычисляются сразу до тех пор пока хоть одно из них не даст TRUE, и только потом идёт выполнение одного из блоков этого оператора, и на этом оператор IF заканчивает своё выполнение.
В Вашем же варианте после выполнения одного из блоков могут начать вычисляться другие условия того же оператора IF.
Думаю, это слишком нестандартное изменение семантики давно известного оператора, не взлетит, как не взлетели всякие циклы-пауки, например...
-
Да не меняется тут семантика. Это сахар.
IF cond1 THEN
ANDIF cond2 THEN
END;
Транслируется в:
IF cond1 THEN
IF cond2 THEN
END;
END;
Абсолютно ничего не меняется кроме способа записи. Ровно точно так же как ELSIF сахар для следующего:
IF cond1 THEN
ELSE
IF cond2 THEN
END;
END;
ANDIF - это ELSIF наоборот.
ps Но отрицательный отзыв принят :) Видимо отдельная конструкция будет более понятной.