Читать книгу Код. Культура, скомпилированная в байты - - Страница 11

ЧАСТЬ I: ФИЛОСОФИИ
Глава 2. Синтаксис как мировоззрение
2.1. Скобки, отступы и границы блоков

Оглавление

В 1972 году Деннис Ритчи работал над языком Си в Bell Labs. Ему нужен был способ обозначить границы блоков кода – условий, циклов, функций. Он выбрал фигурные скобки. Это решение казалось очевидным: B, предшественник Си, уже использовал их, унаследовав от BCPL. Скобки были явными, недвусмысленными, их нельзя было случайно стереть или не заметить на экране телетайпа.

Контекст 1972 года существенен. Программисты работали с терминалами, которые показывали восемьдесят символов в строку. Перфокарты ещё не ушли в прошлое полностью. Пробелы и табуляции были ненадёжны – разные системы интерпретировали их по-разному, разные терминалы отображали их с разной шириной. Фигурные скобки решали практическую проблему: они были видимы, однозначны, устойчивы к ошибкам передачи данных. Один символ – открытие блока. Другой символ – закрытие. Никакой двусмысленности.

Это решение определило полвека программирования. Java, JavaScript, C#, Go, Rust – все они унаследовали фигурные скобки от Си. Целое семейство языков думает о структуре кода одинаково: вот открывающая скобка, вот закрывающая, между ними – тело блока. Отступы при этом остаются рекомендацией, конвенцией, делом вкуса. Компилятору всё равно, как вы расставите пробелы. Он смотрит только на скобки.

Можно написать программу на Си, где весь код идёт в одну строку. Компилятор не возразит. Можно расставить отступы хаотично, вразнобой. Компилятор скомпилирует. Фигурные скобки – единственный источник истины о структуре. Всё остальное – косметика для человеческих глаз.

Семнадцать лет спустя, в декабре 1989 года, Гвидо ван Россум начал работу над Python в Центре математики и информатики в Амстердаме. Он сделал противоположный выбор: никаких скобок для обозначения блоков. Только отступы. Структура кода должна быть видна сразу, без необходимости искать парные символы.

Ван Россум не изобрёл эту идею. Он унаследовал её от ABC – образовательного языка, над которым работал в том же исследовательском центре. «Я создал базовый синтаксис, использовал отступы для группировки вместо фигурных скобок или блоков begin-end», – вспоминал он позже в интервью. ABC, в свою очередь, возможно, заимствовал эту концепцию от языка occam. Но именно Python сделал значимые отступы массовым явлением.

Почему ван Россум сохранил этот выбор, хотя мог отказаться от него, как отказался от других особенностей ABC – например, от ключевых слов в верхнем регистре? Потому что отступы решали реальную проблему. «Я привык к этой возможности, работая с ABC», – объяснял он в одном из интервью, – «она устраняла определённый тип бессмысленных споров, распространённых среди программистов на C: куда ставить фигурные скобки».

За этим стоит глубокое убеждение: код читают чаще, чем пишут. Если программисты всё равно используют отступы для визуальной структуры – а они используют, потому что иначе код нечитаем, – почему бы не сделать их обязательными? Форма становится содержанием. То, что вы видите, – это то, что исполняется. Нет разрыва между визуальным восприятием и логической структурой.

Официальная документация Python формулирует это так: ван Россум полагает, что использование отступов для группировки чрезвычайно элегантно и вносит большой вклад в ясность типичной программы на Python. Большинство людей учатся любить эту особенность через некоторое время.

Haskell, появившийся годом позже Python, в 1990 году, тоже использует значимые отступы – но иначе. В Haskell действует так называемое «правило офсайда» (off-side rule), термин, введённый Питером Ландином ещё в 1966 году. Отступы определяют границы блоков после ключевых слов where, let, do и of. Но в отличие от Python, Haskell предлагает альтернативу: можно использовать фигурные скобки и точки с запятой явно. Большинство программистов на Haskell этого не делают – консенсус в том, что значимые отступы делают код красивее. Но выбор есть.

Это различие показательно. Python категоричен: отступы – единственный способ. Haskell гибок: отступы – предпочтительный способ, но не единственный. За этим стоят разные философии. Python создавался для людей, которые учатся программировать, – им не нужен выбор, им нужна ясность. Haskell создавался для исследователей и экспертов – им нужна гибкость, возможность выразить намерение разными способами.

Философия фигурных скобок – это философия свободы и явности. Программист сам решает, как форматировать код. Компилятор доверяет ему. Границы блоков обозначены явно, их можно увидеть даже в однострочной записи. Да, это порождает бесконечные споры о стиле: скобка на той же строке или на новой? Отступ в два пробела или в четыре? Пробел перед скобкой или нет? Но эти споры – цена свободы. Каждая команда, каждый проект может выбрать свой стиль.

Философия значимых отступов – это философия принудительной ясности. Язык не доверяет программисту форматировать код правильно. Или, точнее, язык не видит разницы между «неправильно отформатированным» и «неправильным» кодом. Если отступ не соответствует логике – это синтаксическая ошибка, а не вопрос стиля. Споры о форматировании невозможны, потому что формат – часть синтаксиса. Код, который компилируется, автоматически правильно отформатирован.

Третий подход – ключевые слова – выбрали Pascal с его begin и end, Ruby с его do и end, Ada с её begin и end. Это компромисс: явные маркеры, как скобки, но более читаемые для человека. Вместо абстрактных символов – слова естественного языка. Код читается почти как проза: «если условие, тогда начало… конец». Никлаус Вирт, создатель Pascal, верил в самодокументирующийся код. Ключевые слова делают структуру понятной даже тому, кто видит программу впервые.

Каждый подход отражает ценности эпохи и создателей.

Си появился в мире ограниченных ресурсов, где каждый символ на счету, где надёжность важнее красоты. Телетайпы печатали медленно. Память измерялась килобайтами. Фигурная скобка – один символ вместо пяти букв слова begin. В таком мире минимализм – не эстетический выбор, а необходимость.

Python появился в мире, где главным ресурсом стало время программиста, где читаемость важнее компактности. К 1989 году память подешевела, экраны стали большими, а программы – сложными. Узким местом стал не компьютер, а человек. Ван Россум оптимизировал для человека.

Pascal появился в академическом мире, где программирование было частью образования, где код должен был учить структурному мышлению. Вирт хотел, чтобы студенты видели структуру программы, читали её как текст. Ключевые слова делали это возможным.

Ruby появился в мире, где счастье программиста объявлялось явной целью. Юкихиро Мацумото хотел, чтобы код был приятен глазу и разуму. Ruby использует end для закрытия блоков, но позволяет опускать его в однострочных конструкциях. Гибкость ради красоты.

Показательно, как развивались языки со временем. Си остался верен скобкам – это часть его идентичности, его наследия, его культуры. Python никогда не рассматривал возможность добавить скобки как альтернативу – это разрушило бы его философию. Haskell сохранил оба варианта, но сообщество однозначно предпочитает отступы.

А Go, созданный в 2009 году людьми из той же традиции Bell Labs, что и Си, пошёл дальше. Он не просто сохранил скобки, но добавил gofmt – инструмент, который автоматически форматирует код единственным «правильным» способом. Не рекомендуемым. Не предпочтительным. Единственным.

«Gofmt’s style is no one’s favorite, yet gofmt is everyone’s favorite», – гласит один из Go Proverbs. Стиль gofmt – ничей любимый, но сам gofmt – всеобщий любимый. В этой формуле – признание, что споры о стиле бессмысленны, и одновременно решение: пусть машина решит за всех. Никто не получает свой любимый стиль. Но никто и не спорит. Это не компромисс – это капитуляция перед неразрешимостью конфликта.

Go – эволюция философии Си. Создатели Go поняли то, чего не знали создатели Си: свобода форматирования оказалась не ценностью, а источником конфликтов. Десятилетия священных войн о стиле. Тысячи часов, потраченных на споры о расположении скобок. Go устранил саму возможность спора. Автоформатирование при сохранении файла. Один стиль для всех. Мир через единообразие.

Этот подход распространился. Python получил black – «бескомпромиссный форматтер», который тоже не предлагает выбора. JavaScript получил prettier. Rust получил rustfmt. Индустрия пришла к пониманию, которое Go сформулировал первым: лучший способ закончить спор о форматировании – сделать его невозможным.

Код. Культура, скомпилированная в байты

Подняться наверх