Виправдайте GOTO!

У списку вічних питань ІТ, дати відповідь на які не вдається мало не з самого початку комп'ютерної ери, тема порочності оператора GOTO стоїть осібно. Спливна регулярно на протязі ось вже без малого шість десятиліть (та чи є хоч один інший такий приклад ?!), просто вражає, якого напруження дискусії вона провокує і скільки помилок пов'язано з нею до сих пір! Днями це сталося в черговий раз на Технофорум Slashdot - і я не втримався від спокуси розставити крапки над i.

Якщо ви коли-небудь програмували - на будь-якій мові! - то, звичайно, в курсі дилеми. І швидше за все налаштовані проти GOTO. Принаймні саме таке враження про компьютерровской аудиторії склалося у мене за роки роботи в журналі: всякий раз, коли я згадував, що починав свою програмістську кар'єру з бейсика, неодмінно знаходилися ті, хто вказував мені на «понівечений моїх мізків розпусним дією оператора безумовного переходу ». Але - куди діватися? Усі ранні мови високого рівня - COBOL, FORTRAN, BASIC і інші - запозичили безумовний перехід з асемблера. І хоч збереглися спогади, що вже в 1959-му році хтось Heinz Zemanek (Один з батьків мови PL / I) висловлював сумніви в необхідності оператора, тільки в 1968-му питання отримав по-справжньому широкого розголосу.

Дякувати за це слід Едсгер Дейкстрой і Ніклауса Вірта: перший написав коротку статтю про небезпеки GOTO, другий перейменував її в «GOTO considered harmful» ( «GOTO небезпечний»), зробивши її, як ми сказали б зараз, вірусної. Результат? Словосполучення considered harmful стало мемом , А прихильність безумовному переходу ось уже півстоліття вважається ознакою поганого смаку!

У списку вічних питань ІТ, дати відповідь на які не вдається мало не з самого початку комп'ютерної ери, тема порочності оператора GOTO стоїть осібно

«... неможливо навчити хорошому програмування студентів, що починали з BASIC: як програмісти, вони безнадійно ментально покалічені» (Е.Дейкстра).

Оригінал тієї статті, до речі, ось - якщо тільки ви в силах переварити оригінального Дейкстрой: читається він, відверто кажучи, важко. Але якщо ризикнете, знайдете там чимало цікавого, починаючи прямо з його спостереження, що «якість програміста обернено пропорційно кількості GOTO в його коді». Називати такий код «схожим на спагетті» стали пізніше, але в тексті Дейкстри є ще як мінімум одна примітна річ: посилання на математичне доказ відсутності необхідності GOTO, сформульоване Джузеппе Якопіні (пізніше воно було названо теоремою Бема-Якопіні). Суть: машина Тьюринга може бути побудована без використання GOTO, тільки лише залученням трьох структур управління: послідовного виконання, розгалуження і циклів.

До речі, Дейкстра повернувся до питання двадцять років по тому, більш ясно сформулювавши дурощі вплив безумовного переходу на образ мислення програміста. Нібито, замість того, щоб продумувати алгоритм, програмер піддається спокусі понатикати всюди GOTO - чим погіршує читаність коду і робить програму менш надійною і передбачуваною.

Здавалося б, цього достатньо, щоб поставити в суперечці крапку - і творці багатьох високорівневих мов так і зробили, принципово проігнорувавши GOTO або навіть посміявшись над своїми «не дуже далекими колегами» (в Python включений модуль з такою назвою, випущений 1 квітня 2004 року: він працює, так, емулюючи безумовний перехід засобами мови, але мета була саме підколоти супротивників в суперечці). Ось тільки і прихильників GOTO залишилося чимало - і безпосередньо, або емуляцією, оператор безумовного переходу був реалізований в безлічі високорівневих мов і після Дейкстри.

Взагалі-то, уважно вчитавшись, ви виявите, що і сам Дейкстра Не ​​проти GOTO як такого, він лише проти його необмеженого використання. Проте найкраще на захист нещасного оператора виступив великий практик Лінус Торвальдс - в порівняно недавній дискусії з колегами по ядру Linux. Ось вона - і, на відміну від пишномовного Дейкстри, Торвальдс читається легко.

Ось вона - і, на відміну від пишномовного Дейкстри, Торвальдс читається легко

«Говорити легко, ви код покажіть!» (Л.Торвальдс).

Сенс його листів: всупереч усталеному думку, GOTO може робити код більш зрозумілим - зокрема там, де відсутність безумовного переходу вимагає сильного ускладнення програми (наприклад, при перехопленні помилок). Далі, всупереч все тому ж думку, явно чи приховано GOTO присутній майже у всіх мовах: перевірка з переходом - це GOTO, примусовий вихід із циклу - теж. А віртовскій Pascal, на який так люблять посилатися противники GOTO (оператор там спочатку був відсутній, але пізніше був доданий, погіршивши читаність коду), Лінус називає проблемою автора мови, пошкодивши розумом, а не проблемою GOTO: мова цей, на думку Торвальдса, непридатний для практичного застосування, тільки для навчання. До речі, і «читаність» в розумінні Лінуса має чисто практичний сенс: покращуючи її, ви робите код компактнішою і простіше.

Так що використовуйте GOTO і не сумнівайтеся - як не сумніваються автори лінуксового ядра, в якому десятки тисяч безумовних переходів. І не піддавайтеся спробам промити вам мізки теоретиками комп'ютерних наук, взрощенний на роботах мало що розуміли в практиці Вірта і Дейкстри!

І ось цього вже зовсім точно вистачить, щоб припинити суперечку. Хоч обидва учасники і викладають свої думки в досить радикальній манері (ніж «якість програміста» Дейкстри краще «пошкодження мозку» Торвальдса?), Вони не намагаються зробити їх істиною в останній інстанції. Якщо вчитатися, обидва просто ратують за вдумливе використання оператора GOTO. А то, що їх слова використовуються для роздування холівара - провина не Торвальдса або Дейкстри (до того ж давно покійного, так що змагання нечесне), а інтернет-коментаторів, спраглих затвердити свою думку як єдино правильне. Тільки подивіться як починається та дискусія з Лінусом: приходить якийсь початківець розробник і (буквально!), Спираючись лише на один приклад, декларує, що, мовляв «GOTO поганий, дуже поганий!».

Так не повторюйте чужих помилок, які не лийте масла в вогонь марного спору. Якщо вже на те пішло, давно сформульовані типові випадки, коли GOTO може принести користь. І пам'ятайте ще, що мистецтво писати красивий код формалізується погано: один напише гарну програму навіть з GOTO, іншому не допоможе і його відсутність. А GOTO може бути корисний в наступних ситуаціях:

- Щоб зробити код більш читабельним.
- Щоб позбутися від дуплікації коду.
- Щоб реалізувати таблицю переходів (корисна, наприклад, для створення симуляторів обчислювальних систем).
- Щоб вийти з множинного вкладеного циклу.
- Для обробки помилок.

Користуйтеся на здоров'я!

А чи є хоч один інший такий приклад ?
Але - куди діватися?
Результат?
Ніж «якість програміста» Дейкстри краще «пошкодження мозку» Торвальдса?