Мудрость древних
Jun. 19th, 2017 02:48 pmМожет быть интересно только программистам, да и то не всем.
В одном из диалектов языка Паскаль (мне тут кстати подсказали, что 19 июня - день рождения Паскаля; я и в мыслях не имел приурочивать, так само вышло), которым мне доводилось пользоваться, был придуман оператор, ни механизма работы, ни смысла которого я в детстве не понимал, и никто из спрошенных мной взрослых тоже не понимал — наверное, потому, что понятие бросаемого исключения хоть уже и существовало, но было эзотерикой, и о setjmp/longjmp тоже ещё никто не слышал.
Сейчас я механизм работы понимаю, но инопланетность разума, придумавшего такое, меня продолжает удивлять.
Итак, цитата из документации (приводится в современной редакции):
Всё понятно? :) Сможете написать программу, использующую оператор ветвления в мирных целях?
Если нет, то вот пример из документации (приводится в сокращении):
Эта программа печатает
Теперь, надеюсь, всё понятно?
Следующая программа на С++ работает аналогично:
В одном из диалектов языка Паскаль (мне тут кстати подсказали, что 19 июня - день рождения Паскаля; я и в мыслях не имел приурочивать, так само вышло), которым мне доводилось пользоваться, был придуман оператор, ни механизма работы, ни смысла которого я в детстве не понимал, и никто из спрошенных мной взрослых тоже не понимал — наверное, потому, что понятие бросаемого исключения хоть уже и существовало, но было эзотерикой, и о setjmp/longjmp тоже ещё никто не слышал.
Сейчас я механизм работы понимаю, но инопланетность разума, придумавшего такое, меня продолжает удивлять.
Итак, цитата из документации (приводится в современной редакции):
Оператор ветвления (branch)
Синтаксис
<Оператор ветвления> ::= branch <Выражение> of <Оператор> { ; <Оператор> }*** endСемантика
При передаче управления на оператор ветвления вычисляется <Выражение>, которое должно быть простого типа, далее управление передаётся на первый оператор в ветке. Если j-ый оператор ветки закончился, то происходит выход из ветки и управление передаётся за end. При исполнении j-го оператора может быть выполнен оператор back.Синтаксис оператора back
<Оператор back> ::= back <Выражение>
При выполнении оператора back вычисляется выражение и находится наиболее динамически предшествующая ветка с совместимым значением выражения. Значения совместимы, если либо они равны, либо одно из них равно нулю.
После нахождения такой ветки управление передаётся следующему в ветке оператору, либо, если выполнялся последний оператор, за end ветки.
Если не найдётся ветки с совместимым выражением, то считается, что программа заключена в оператор
branch <Программа>; begin <Вывод текста "Выход по ALT"> end end
Всё понятно? :) Сможете написать программу, использующую оператор ветвления в мирных целях?
Если нет, то вот пример из документации (приводится в сокращении):
program t;
procedure m(i: integer);
begin
branch i of
begin
if i<20 then begin
m(i+1);
back i-2
end
end;
writeln(i)
end
end;
begin
m(0)
end.Эта программа печатает
17
14
11
8
5
2
0Теперь, надеюсь, всё понятно?
Следующая программа на С++ работает аналогично:
#include <iostream>
void m(int i) {
try {
if (i < 20) {
m(i+1);
throw i-2;
}
} catch (int k) {
if (i != 0 && k != 0 && i != k) throw;
std::cout << i << '\n';
}
}
main() {
m(0);
}
no subject
Date: 2017-06-19 11:30 pm (UTC)no subject
Date: 2017-06-19 11:43 pm (UTC)Можно написать
branch 1.0 of back 1; writeln('Caught real') endи оно не поймается (хотя 1.0, конечно же, равно 1), а выйдет на "выход по alt" (AKA terminate()).
no subject
Date: 2017-06-20 12:05 am (UTC)no subject
Date: 2017-06-20 12:10 am (UTC)no subject
Date: 2017-06-20 12:26 am (UTC)no subject
Date: 2017-06-20 12:31 am (UTC)no subject
Date: 2017-06-20 05:50 am (UTC)no subject
Date: 2017-06-20 06:06 am (UTC)Вообще типичная для науки ситуация — вроде бы придумал что-то более-менее, но объяснить хорошим академическим языком пока слабо. И вот в угоду программным комитетам и редколлегиям переделываешь через задний проход, но зато так, что можешь в тексте описать.
Правда это как раз контрпример: современные структурные исключения попроще будут и в описании, и в освоении. Сейчас эта конструкция конечно выглядит примерно как выписывание сопроцедур через call/cc при наличии в языке нормальных сопроцедур =).
no subject
Date: 2017-06-20 06:28 am (UTC)no subject
Date: 2017-06-20 06:47 am (UTC)no subject
Date: 2017-06-20 07:08 am (UTC)no subject
Date: 2017-06-20 07:49 am (UTC)no subject
Date: 2017-06-20 03:58 pm (UTC)no subject
Date: 2017-06-20 06:10 pm (UTC)http://www.cs.dartmouth.edu/~mckeeman/cs48/mxcom/doc/ReferenceX.pdf
http://www.cs.dartmouth.edu/~mckeeman/cs48/mxcom/doc/Emitter.html
Там даже и есть ситуация, когда ни одна из альтернатив в операторе if не подходит, программа убивается.
no subject
Date: 2017-06-20 06:54 pm (UTC)И у Дейкстры нет никаких нелокальных переходов.
no subject
Date: 2017-06-20 07:05 pm (UTC)_program t; _begin _back 0 _end.
БЫЛИ ОШИБКИ В АВТОКОД ПРОГРАММЕ
Логично. Текстуально оператор back может быть где угодно, но если он есть, а branch - нет, то это точно ошибка.
Тест №2:
_program t; _begin _back 0; _branch 0 _of ; _end _end.
КОНТРОЛЬ КОМАНДЫ
Позор, конечно, но более или менее логично. Если еще не было ни одного branch, то обработчик "выход по alt" может быть еще не установлен.
Тест №3:
_program t; _begin _branch 0 _of ; _end; _back 0 _end.
КОНТРОЛЬ КОМАНДЫ
И так у них всё. :)
no subject
Date: 2017-06-20 07:18 pm (UTC)