?

Log in

No account? Create an account

Мудрость древних - Общество дровосеков Бердичева по изучению Мишны

Jun. 19th, 2017

02:48 pm - Мудрость древних

Previous Entry Share Next Entry

Может быть интересно только программистам, да и то не всем.

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


This entry was originally posted at http://spamsink.dreamwidth.org/1053282.html. Please comment there using OpenID.

Comments:

[User Picture]
From:move2winnipeg
Date:June 19th, 2017 11:17 pm (UTC)
(Link)
Можно для сельской бедноты пояснить, чем ветвление отличается от if/else?
Спасибо :)
(Reply) (Thread)
[User Picture]
From:spamsink
Date:June 19th, 2017 11:31 pm (UTC)
(Link)
Вот-вот. :) Педагогическим даром автор инструкции явно не обладал.
Несколько минут назад я обновил пост, добавив эквивалентную программу на C++.
Почему эту штуку назвали "ветвлением" - бог весть.

Edited at 2017-06-19 11:33 pm (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:move2winnipeg
Date:June 19th, 2017 11:36 pm (UTC)
(Link)
Я не подколоть ради, просто стараюсь понять все алгоритмы, что под руку попадаются :)
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 20th, 2017 12:21 am (UTC)
(Link)
Мне интересно, откуда ноги растут. Диагностику "выход по alt" русский человек сам не придумает.
(Reply) (Parent) (Thread)
[User Picture]
From:move2winnipeg
Date:June 19th, 2017 11:44 pm (UTC)

Фух, отпустило...

(Link)
Я, как всегда, думал, что это я дебил :)
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 20th, 2017 12:21 am (UTC)

Re: Фух, отпустило...

(Link)
У меня руки не доходили разобраться, что делает эта конструкция, больше 30 лет. Так что главный дебил здесь я!
(Reply) (Parent) (Thread)
From:t_mike
Date:June 20th, 2017 03:13 am (UTC)
(Link)
это в честь для рождения Блеза Паскаля? :)
(Reply) (Thread)
[User Picture]
From:spamsink
Date:June 20th, 2017 03:33 am (UTC)
(Link)
Ух ты! Я и понятия не имел, чистое совпадение!
(Reply) (Parent) (Thread)
[User Picture]
From:real_big_shish
Date:June 20th, 2017 04:34 am (UTC)
(Link)
Да, это вам не case of
(Reply) (Thread)
[User Picture]
From:ilya_dogolazky
Date:June 20th, 2017 06:08 am (UTC)
(Link)
это наверное не глагол, а существительное "ветка №i"
(Reply) (Thread)
[User Picture]
From:spamsink
Date:June 20th, 2017 06:11 am (UTC)
(Link)
Что именно не глагол?
(Reply) (Parent) (Thread)
[User Picture]
From:ilya_dogolazky
Date:June 20th, 2017 06:12 am (UTC)
(Link)
слово «branch». Интересно, а слово back может стоять вне блока branch?
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 20th, 2017 06:16 am (UTC)
(Link)
Оно нигде в качестве глагола и не используется. "case" в
операторе "case <выражение> of ..." тоже не глагол.

Может. Например, "back i-2" может быть вынесено в отдельную процедуру, и будет работать точно так же.
(Reply) (Parent) (Thread)
[User Picture]
From:ilya_dogolazky
Date:June 20th, 2017 06:20 am (UTC)
(Link)
кое где это слово используется как глагол, в армовском асемблере например "b", "bl"

Edited at 2017-06-20 06:21 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:spamsink
Date:June 20th, 2017 06:29 am (UTC)
(Link)
В ассемблере это команда (инструкция), а здесь - оператор. :)
"Нигде" подразумевает "в контексте поста", а не во Вселенной.

Edited at 2017-06-20 06:30 am (UTC)
(Reply) (Parent) (Thread)
[User Picture]
From:fatoff
Date:June 21st, 2017 04:26 am (UTC)
(Link)
То классический процедурный язык, кем-то недоулучшенный после Вирты. Вот в наше время... Уровень экспресии в декларативных языках такой, что им ещё нужен и скриптовый, чтобы что-то разветвить от условия.
(Reply) (Thread)
From:dolovar
Date:August 28th, 2017 12:14 pm (UTC)
(Link)
Предполагаю, что автор конструкции хотел реализовать рекурсию без напряжения стека.
(Reply) (Thread)
[User Picture]
From:spamsink
Date:August 31st, 2017 09:34 pm (UTC)
(Link)
Точнее, без введения дополнительных локальных переменных-флагов в локальном фрейме, которые бы реплицировались при рекурсии, а использовались бы редко. Возможно, это соображение тоже повлияло. Мне подсказали, что играть с разнообразными реализациями бэктрекинга ради реализации "искусственного интеллекта" было модно в начале 70-х годов, и на этот счёт были статьи в журналах ACM. Видимо, из какой-то из них и была почерпнута идея, вместе с формулировкой "выход по альтернативе".
(Reply) (Parent) (Thread)