// вернуться к предисловию

Постановка: GOTO однозначно зло, приводит к лапшевидному коду, невозможно понять, невозможно поддерживать, противоречит всем парадигмам в мире, от него ещё прадеды наши отказались, всё такое.


Феномен GOTO занимает меня давно по множеству причин.

Во-первых, я начал программировать во времена толерантности к этой команде. Не было Java и Python, были BASIC и Pascal, а учебники дежурно советовали использовать GOTO по нужде. Надо? Используй. Вот тебе ещё и примеры уместности. Потому процесс безжалостного форматирования поколений разработчиков смог пронаблюдать с практического начала.

Во-вторых, до сих пор многие языки содержат GOTO, но редкий современный разработчик в новых проектах встретит использование. Идём по TIOBE: C (есть), Java (есть в виде резерва – ситуация «слово есть, а жопы нет»), Python (нет), C++ (есть), C# (есть), Visual Basic (есть), JavaScript (нет, но есть break и continue на метку), PHP (есть), Go (есть), Swift (нет), Rust (нет), Ruby (нет).

В-третьих, исходный текст за десятилетия был извращён дважды, о чём скажу далее.

В-четвёртых, редкая тема так подрывает со стульев. Можете провести эксперимент: подсунуть на code review что-то с GOTO – запасайтесь попкорном и наблюдайте за выражением лиц читателей.


С чего всё началось?

В далёкие-далёкие времена (1968 год) Эдсгер Вибе Дейкстра набросил на вентилятор, опубликовав в Communications of the ACM письмо, кликбейтовое название которого придумал редактор: «Go To Statement Considered Harmful».

Дейкстра указал на следующее:

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

Ключевая военная фраза письма: «the go to statement should be abolished from all “higher level” programming languages (i.e. everything except — perhaps — plain machine code)».

Ну а наброс со старта вот такой: «Since a number of years I am familiar with the observation that the quality of programmers is a decreasing function of the density of go to statements in the programs they produce».

И всё завертелось.

PS. Настолько кликбейт, что появились десятки подражаний и вообще вошло в язык.


Что тут надо понимать?

Во-первых, это было мнение. Встречаю немало людей, считающих, что Дейкстра однажды опубликовал большую научную работу, доказывающую, что GOTO зло. Нет. Было опубликовано письмо на страницу с четвертью (скан), письмо, начинающее публичную полемику. Да и всё. Не аксиома, не теория, не теорема, не докторская, не кандидатская. Чувак написал «этот ваш GOTO фигня, не используйте его». На него могли даже внимание не обратить, в CACM куча всего публиковалась (а сейчас журнал похож на рекламный каталог, не подписывайтесь, бяка).

Во-вторых, эти теоретические рассуждения как-то не особо повлияли на практиков, насколько могу судить (по старому коду, по листингам в старых журналах, по старым книгам). Если думаете, что после 1968 года мир изменился, вы ошибаетесь. Как использовали GOTO, так и продолжили (собсно, в актуальных языках 1970-х сложно было без GOTO). Зато возбудились воины печати.

В-третьих, таки полемика развернулась. Если ваш собеседник заявляет «почему не использовать GOTO? ну это же очевидно!», отойдите от него – Наполеон сбежал из палаты, ему очевидно то, что не очень очевидно поколениям программистов и учёных (включая Дональда Кнута, к слову, с его «Structured Programming with Goto Statements»).


Про извращения.

Извращение №1. К сожалению, 9/10 людей предпочитают повторять удобные фразы, превращая их в мемы, но не читать тексты, в которых эти фразы появились. Можете себя проверить: сначала вспомните, что вы знаете и думаете про «религия – опиум для народа», затем почитайте «Опиум народа». Та же фигня произошла и с Дейкстрой. Смысл его письма не именно в борьбе против GOTO, но в борьбе с плохо и непонятно структурированным кодом (аналогия по опиуму – борьба не с поповством, но с религией). GOTO – наглядная иллюстрация, не более (но и не менее). А народ кинулся уничтожать.

Извращение №2. Ещё раз: Дейкстра против плохо структурированного кода. В конце концов, он один из ключевых авторов структурного программирования, призванного в числе прочего сделать код чище и понятнее. И как это понял народ? Окей, мы тут перестали использовать GOTO, но вовсю используем break / continue label. Ахаха. Это тот же GOTO, только специализированный. Ну а что? Называется же иначе! Всё по Дейкстре!

Постизвращение. Даже если вы не используете GOTO, BREAK, CONTINUE и т.п., но ваш код представляет собою циклы в циклах с ветвлениями, а вот тут функция вызывает функцию, которая вызывает функцию, которая рекурсивно… ой… ага, снова два цикла в цикле, а давайте case в case сунем! В общем, вы не отказались от GOTO. Хорошо архитектурный код с GOTO гораздо ближе идеям Дейкстры, чем ваша лапша с винегретом из ООП и функционального программирования, накостыленная впопыхах, лишь бы к релизу падающего сервера успеть. Юмор в том, что вашу лапшу на code review лид пропустит, а вот чистый код с GOTO у него вызовет сердечный приступ.

Всё усложняется ещё и тем, что сортов GOTO вовсе не один. А каждый читает то, что его глаза хотят и могут прочитать. А уж трактуют… Есть особая дисциплина под ковром: разбирательство с тем, что же, блин, на самом деле хотел сказать автор. Я вон вижу борьбу с лапшой. Иванов видит войну именно с GOTO. Петров видит не просто с GOTO, но с определёнными GOTO (плохими! а вот те другие хорошие!). Сидоров после порции расширяющего сознание видит шаги к метаязыку всего и вся. Если мерно рыскать по сети в поисках исторических (и не очень) дискуссий, возвращаешься к письму и перечитываешь, чтобы увидеть там увиденное участниками драки. Получается не всегда.


Контекст.

Хорошо бы также помнить о контексте, в котором рождается что-либо. Письмо Дейкстры – творение эпохи, в которую не было таких клёвых IDE, как сейчас. И таких мониторов больших не было. У вас не было ничего:

  • ни навигации по коду;
  • ни подсветки кода;
  • ни хорошо интерактивной отладки;
  • ни развитых средств проверки кода на ошибки.

НИ. ЧЕ. ГО.

Ясен ясень, вы ушатаетесь разбирать код на 200..300 строк, в котором управление прыгает вверх-вниз. В моём детстве такой код печатался на матричном принтере, потом мы цветными ручками рисовали стрелки от GOTO к меткам и прочее. Это и в самом деле было проблемой.

А сейчас такой код не проблема. Что в Visual Studio, что в IDE на базе IntelliJ IDEA, да даже в редакторе Sublime Text у меня нет этой проблемы. Удобство работы с кодом за 50 лет повысилось в десятки раз. Строго говоря, уже и по сотням тысяч строк кода шастаешь вполне уверенно.


Немножко капитанства.

Все эти теории пропадают, едва мы оказывается на уровне ассемблера и машинных кодов. JMP свят, вечен и вездесущ. Тут не могу не упомянуть всё ту же Java, у которой goto на уровне языка в резерве и не используется, а вот на уровне byte code их два: goto и goto_w, используются вовсю.

Не упоминал бы, но встречал людей, считающих, что GOTO ни в каком виде нет нигде. Понятно, что эти люди… скажем, очень высокоуровневые в своей работе разработчиками, но вдруг вы такой же. Так вот, в компьютерах всё на месте.


Так использовать или нет?

Я для своих внутренних утилит (код которых никто не увидит, а если увидит, так это не мои проблемы) использую.

А вот если код для внешнего мира, так не использую. Не потому, что… но… скажем так, мне экономия моего времени сейчас важнее, чем переубеждение кого-либо в чём-либо, от чего не зависят жизни и здоровье людей. И если код без GOTO я могу написать за 30 минут и за 5 минут пропустить его через смотрящего (или же быстро объяснить джуниору), то код с GOTO (написанный за 5 минут) вызовет цирк на час-другой, в конце которого я от цирка устану, махну рукой и за 30 минут напишу то, от чего у мальчиков щёчки не краснеют.

Цель эссе – показать вам, что всё не так однозначно, не так раз и навсегда прибито гвоздями.


Факультативное чтение (вовсе не исчерпывающее или стройно-цельно по теме, но примеры вокруг проблемы):


// вернуться к предисловию