spamsink: (Default)
[personal profile] spamsink
Может быть интересно только программистам, да и то не всем.

В одном из диалектов языка Паскаль (мне тут кстати подсказали, что 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);
}

Date: 2017-06-19 11:30 pm (UTC)
sab123: (Default)
From: [personal profile] sab123
Ну как бы понятно, что тут i - _тип_ исключения, а 0 - базовый тип, который ловит все. Но, конечно, жуткая вещь, и пример скорее все запутывает, чем поясняет.

Date: 2017-06-20 12:10 am (UTC)
vak: (Default)
From: [personal profile] vak
Порылся на besm6.github.io и с удивлением отыскал эту загогулину в документации на Паскаль-Автокод. Ужас какой! По жизни никогда не встречал такую конструкцию. Небось Пирин добавил для упрощения защиты диссертации.

Date: 2017-06-20 12:31 am (UTC)
vak: (Default)
From: [personal profile] vak
Я наверняка встречал её в доментации, но напрочь забыл. А в реальном коде branch никогда не попадался.

Date: 2017-06-20 07:18 pm (UTC)
vak: (Default)
From: [personal profile] vak
Как обычно, реализация подвела. :)

Date: 2017-06-20 06:06 am (UTC)
dluciv: (Default)
From: [personal profile] dluciv
Касательно диссертации...

Вообще типичная для науки ситуация — вроде бы придумал что-то более-менее, но объяснить хорошим академическим языком пока слабо. И вот в угоду программным комитетам и редколлегиям переделываешь через задний проход, но зато так, что можешь в тексте описать.

Правда это как раз контрпример: современные структурные исключения попроще будут и в описании, и в освоении. Сейчас эта конструкция конечно выглядит примерно как выписывание сопроцедур через call/cc при наличии в языке нормальных сопроцедур =).
Edited Date: 2017-06-20 06:07 am (UTC)

Date: 2017-06-20 05:50 am (UTC)
dluciv: (Default)
From: [personal profile] dluciv
Действительно инопланетная конструкция...

Date: 2017-06-20 06:47 am (UTC)
yurikhan: (Default)
From: [personal profile] yurikhan
Я б, увидев такой эквивалентный код на плюсах в ревью, наверно, руки бы сразу оторвал, по самую ж… уши. Это же лапша похуже, чем goto.

Date: 2017-06-20 07:49 am (UTC)
yurikhan: (Default)
From: [personal profile] yurikhan
Нет, эквивалентность более-менее понятна. Но исходный пример злой и не демонстрирует пользы конструкции.

Date: 2017-06-20 06:10 pm (UTC)
sab123: (Default)
From: [personal profile] sab123
"Alt" может происходить от слова альтернатива, вот нашлось про какой-то придуманный Дейкстрой древний язык:

http://www.cs.dartmouth.edu/~mckeeman/cs48/mxcom/doc/ReferenceX.pdf
http://www.cs.dartmouth.edu/~mckeeman/cs48/mxcom/doc/Emitter.html

Там даже и есть ситуация, когда ни одна из альтернатив в операторе if не подходит, программа убивается.

Profile

spamsink: (Default)
spamsink

June 2017

S M T W T F S
    1 23
4 5 678910
111213 141516 17
18 1920 21 222324
252627282930 

Most Popular Tags

Style Credit

Expand Cut Tags

No cut tags
Page generated Jun. 27th, 2017 03:27 am
Powered by Dreamwidth Studios