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

Код
Культура, скомпилированная в байты
Сергей Кирницкий
Дизайнер обложки Grok
© Сергей Кирницкий, 2025
© Grok, дизайн обложки, 2025
ISBN 978-5-0068-7698-9
Создано в интеллектуальной издательской системе Ridero
Введение: Код как культурный артефакт
В.1. Вопрос, который редко задают
Почему существует более семисот языков программирования?
Вопрос кажется странным. Машине безразлично, на чём написан код – она исполняет байт-код, последовательность нулей и единиц. Компилятор переводит любой синтаксис в одни и те же машинные инструкции. С точки зрения процессора нет никакой разницы между программой на Python и программой на Go, между Haskell и JavaScript. Результат один – электрические импульсы в кремниевых схемах.
Но мы, люди, спорим о языках программирования с жаром, который удивил бы стороннего наблюдателя. Мы ведём священные войны о табуляциях и пробелах, о скобках и отступах, о статической и динамической типизации. Мы создаём манифесты и пишем гневные посты в блогах. Мы выбираем стороны и защищаем свой выбор с религиозным пылом.
Это не рациональное поведение, если языки – просто инструменты. Плотник не спорит о философских основаниях молотка. Хирург не пишет манифестов о скальпеле. Но программисты – спорят и пишут. И делают это десятилетиями.
Значит, языки программирования – не просто инструменты. Они что-то большее. Но что именно?
Каждый язык программирования – это материализованный ответ на вопрос: как должен думать человек, общаясь с машиной? И разные люди в разных обстоятельствах дают разные ответы. Кен Томпсон и Деннис Ритчи в Bell Labs начала семидесятых спрашивали: как переписать операционную систему, чтобы она стала переносимой между машинами? Гвидо ван Россум в амстердамском исследовательском центре конца восьмидесятых спрашивал: как научить людей программировать, не отпугнув их синтаксическим шумом? Джеймс Гослинг в Sun Microsystems начала девяностых спрашивал: как написать код, который переживёт смену железа?
Ответы получились непохожими. И каждый ответ нёс в себе следы вопроса – как река несёт следы истока.
Си появился в мире, где память измерялась килобайтами, а каждый такт процессора был на счету. «C is quirky, flawed, and an enormous success» («Си странен, несовершенен и чрезвычайно успешен»), – напишет позже Деннис Ритчи. В этой фразе – вся судьба языка: несовершенство, которое создатель осознавал с первого дня, и триумф, которого никто не планировал. Java появилась в мире корпоративной разработки, где код должен был работать годами без изменений, а команды программистов сменялись быстрее, чем проекты. Отсюда многословность, которую одни считают ясностью, другие – избыточностью. JavaScript появился за десять дней в мае 1995 года, потому что Netscape нужен был скриптовый язык для браузера – и нужен был срочно. Брендан Эйх вспоминал потом, что почти не спал. За эти десять дней он заложил фундамент языка, на котором сегодня работает практически весь интернет.
Десять дней. Семьсот языков. Тридцать лет споров о типизации. Что-то не сходится, если считать это просто инженерией.
Потому что это не просто инженерия. Это культура.
Посмотрим внимательнее на число семьсот. Индекс TIOBE, отслеживающий популярность языков программирования, регулярно фиксирует около ста пятидесяти языков с измеримым уровнем использования. Википедия перечисляет более семисот языков, претендующих на статус «примечательных». Исторический каталог HOPL насчитывает почти девять тысяч языков, когда-либо созданных. При этом реальную долю рынка делят между собой не более двадцати языков, а большинство кода в мире написано на пяти-шести.
Зачем люди продолжают создавать новые языки? Зачем Гвидо ван Россум в 1989 году решил, что миру нужен ещё один язык, когда уже существовали Perl и Tcl? Зачем Брендан Эйх в 1995-м не использовал Scheme или Java, которые уже были готовы? Зачем инженеры Google в 2007 году начали проектировать Go, имея в распоряжении весь арсенал существующих языков?
Ответ всегда один: существующие языки не выражали того, что хотели выразить создатели новых. Не технически – философски. Perl выражал принцип «есть много способов сделать это». Ван Россум хотел выразить противоположное: должен быть один очевидный способ. Java выражала идею корпоративной надёжности и многословной явности. Гослинг хотел, чтобы код был понятен любому инженеру, присоединившемуся к проекту через пять лет. Go выражал идею, что сложность C++ стала непереносимой, и язык должен помещаться в голове программиста целиком.
Новый язык возникает, когда кто-то чувствует: существующие языки воплощают не те ценности. Это культурный акт, не технический.
В.2. Что такое культура языка программирования
Слово «культура» в применении к коду может показаться метафорой. Это не метафора. Это буквальное описание того, чем являются языки программирования.
Культура языка программирования – это совокупность явных принципов, неявных конвенций, инструментов и истории, которые определяют, как на этом языке принято писать и думать. Принято – ключевое слово. Не «как можно» и не «как правильно», а «как принято». Это социальное понятие, не техническое.
Явные принципы фиксируются в документах. Python имеет PEP 20, известный как Zen of Python – девятнадцать афоризмов, написанных Тимом Питерсом в 1999 году. Двадцатый афоризм намеренно оставлен пустым. «Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex.» («Красивое лучше уродливого. Явное лучше неявного. Простое лучше сложного.») Эти строки – не просто рекомендации по стилю. Это философское заявление о том, что такое хороший код. И что важнее – это заявление встроено в сам язык: достаточно написать «import this», чтобы увидеть его на экране. Философия языка доступна в самом языке.
Ruby имеет принцип, который его создатель Юкихиро Мацумото повторял в бесчисленных интервью: «Ruby is designed to make programmers happy» («Ruby создан, чтобы делать программистов счастливыми»). Счастье программиста – не побочный эффект, а цель разработки. В интервью 2003 года он объяснял: «You want to enjoy life, don’t you? If you get your job done quickly and your job is fun, that’s good isn’t it? That’s the purpose of life, partly.» («Вы ведь хотите наслаждаться жизнью? Если вы быстро делаете работу и работа доставляет удовольствие – это ведь хорошо? Отчасти в этом и смысл жизни.») Язык программирования как инструмент для хорошей жизни – это философское утверждение, которое определяет каждое решение в дизайне Ruby.
Go имеет Go Proverbs – набор афоризмов, который Роб Пайк представил на конференции Gopherfest в 2015 году. «Clear is better than clever. A little copying is better than a little dependency. Don’t communicate by sharing memory, share memory by communicating.» («Ясное лучше умного. Немного копирования лучше, чем немного зависимости. Не общайтесь через разделяемую память, разделяйте память через общение.») Каждый афоризм – концентрированное философское утверждение о том, как следует писать программы. Не синтаксическое правило, а принцип мышления.
Неявные конвенции – это то, что не записано в документах, но известно каждому, кто пишет на языке достаточно долго. Это идиоматичный код – код, написанный так, как принято в данной культуре. Синтаксически корректный код на Python может быть совершенно не-питоничным, если он написан в стиле Java. Формально он работает. Культурно он чужероден.
Инструменты воплощают философию не менее красноречиво, чем манифесты. Go поставляется с gofmt – форматировщиком кода, который не имеет опций настройки. Один стиль форматирования на всех. Роб Пайк формулировал это так: «Gofmt’s style is no one’s favorite, yet gofmt is everyone’s favorite». Стиль gofmt – ничей любимый, но сам gofmt – общий любимец. Парадокс разрешается просто: ценность не в конкретном стиле, а в прекращении споров о стиле. Инструмент воплощает философию: единообразие важнее индивидуальных предпочтений.
История создания языка – такая же часть его культуры, как и синтаксис. Go появился в Google в 2007—2009 годах, и это не случайная деталь биографии. К тому моменту в Google работали десятки тысяч инженеров, кодовая база измерялась миллиардами строк, компиляция C++ занимала часы. Роб Пайк вспоминал, что идея Go возникла во время одной такой бесконечной компиляции. «We were not going to continue writing C++” («Мы не собирались продолжать писать на C++»), – говорил он. Go – не абстрактное упражнение в дизайне языков. Это ответ на конкретную боль конкретной компании в конкретный момент времени. Понять Go невозможно, не понимая этого контекста.
Erlang возник в Ericsson, где телекоммуникационные системы должны были работать с надёжностью «девять девяток» – 99,9999999% времени безотказной работы. Это означает менее секунды простоя за тридцать лет. При таких требованиях нельзя позволить себе остановку системы для перезагрузки после ошибки. Отсюда философия Erlang: пусть процессы падают, их перезапустят супервизоры. «Let it crash» («Пусть падает») – не признание поражения, а стратегия надёжности. Система, которая умеет падать и восстанавливаться, надёжнее системы, которая пытается никогда не падать.
Культура языка – это всё вместе: манифесты и молчаливые соглашения, инструменты и история, философия создателей и практика сообщества. Изучить синтаксис языка можно за неделю. Усвоить его культуру – за годы.
Здесь важно сделать оговорку. Когда мы говорим о культуре Python или культуре Go, мы говорим о языках как артефактах, не о людях. Не «программисты на Python думают так», а «Python как язык воплощает такую философию». Разница принципиальна. Программист может использовать Python и не разделять его философию – писать непитонический код, игнорировать PEP 8, нарушать конвенции. Это его право. Но язык останется тем, чем является – артефактом, несущим определённые ценности. Книга исследует артефакты, не людей.
Ещё одна оговорка: описание культуры не означает её оценки. Python не лучше Go, и Go не лучше Rust. Статическая типизация не правильнее динамической, и объектно-ориентированное программирование не превосходит функциональное. Каждый подход – ответ на определённые вопросы в определённом контексте. Описать эти ответы – задача книги. Судить их – нет.
В.3. Карта путешествия
Эта книга – исследование культур языков программирования. Не учебник по синтаксису и не руководство по лучшим практикам. Исследование того, как языки воплощают философии своих создателей, как контекст рождения определяет судьбу языка, как сообщества формируют традиции и ведут войны парадигм.
Зачем это нужно? Гвидо ван Россум сформулировал точно: «You primarily write your code to communicate with other coders, and, to a lesser extent, to impose your will on the computer» («Прежде всего вы пишете код для общения с другими программистами и лишь во вторую очередь – чтобы навязать свою волю компьютеру»). Код – прежде всего коммуникация между людьми. Машина – лишь посредник. Если принять эту точку зрения, культура перестаёт быть опциональным украшением. Она становится основой понимания. Программист, который знает культуру языка, видит за техническими решениями философские выборы. Почему Python использует значимые отступы? Почему Go отказался от исключений? Почему Rust требует явного управления временем жизни ссылок? За каждым из этих решений стоит не только механизм, но и мировоззрение.
Читатель этой книги получит новый взгляд на знакомые инструменты. Не «как это работает», а «почему это так». Контекст для собственного опыта – понимание того, откуда пришли споры о типизации, парадигмах, стилях. Язык для разговора о культуре кода – словарь, позволяющий артикулировать то, что раньше ощущалось интуитивно.
Книга разделена на четыре части, и это деление отражает движение от поверхности к глубине, от настоящего к истокам, от анализа к синтезу.
Первая часть – «Философии» – исследует, что языки говорят о своих создателях. Манифесты, синтаксис, имена – всё это тексты, которые можно читать и интерпретировать. Zen of Python и Go Proverbs – не просто советы по стилю, а концентрированные философские позиции. Выбор между фигурными скобками и значимыми отступами – не технический, а мировоззренческий. Система типов языка отражает убеждения о природе программ и предсказуемости мира.
Вторая часть – «Истоки» – исследует, откуда пришли идеи. Три традиции переплетаются в истории программирования. Системная традиция идёт от Си и Unix: близость к машине, минимализм, доверие программисту. Академическая традиция идёт от Lisp и ML: формальная корректность, математические основания, чистота абстракций. Индустриальная традиция идёт от Java и корпоративных потребностей: масштаб, предсказуемость, экосистема. Современные языки – наследники и синтезаторы этих традиций. Rust сочетает системный минимализм с академической системой типов. TypeScript переносит академические идеи в индустриальную реальность JavaScript.
Третья часть – «Конфликты» – исследует, что происходит, когда философии сталкиваются. Войны парадигм – объектно-ориентированное против функционального, статическая типизация против динамической – это не технические споры. Это конфликты картин мира. За вопросом «нужны ли типы» стоит вопрос о том, можно ли предсказать поведение программы до её запуска. За вопросом «объекты или функции» стоит вопрос о том, как моделировать реальность – как совокупность вещей или как поток преобразований. Open source становится ареной, на которой эти конфликты разворачиваются публично. Корпорации создают языки, и языки несут отпечаток корпоративных культур.
Четвёртая часть – «Эволюция» – смотрит в будущее. Гибридные языки строят мосты между мирами: TypeScript между типизированным и нетипизированным, Kotlin между многословием Java и лаконичностью современных языков. Новый фундамент – Rust, Zig, Mojo – отказывается от legacy ради правильного дизайна с нуля. Искусственный интеллект размывает границы: когда Copilot пишет код, чья это культура? И главный вопрос: движутся ли языки к конвергенции или к специализации? Синтаксис становится похожим, но расходятся ли философии?
Через всю книгу проходит центральная метафора: код как культурный артефакт. Язык программирования – не инструмент, а застывшая философия. Выбор языка – не техническое решение, а культурное позиционирование. Код, который мы пишем, расскажет будущим поколениям не только о наших алгоритмах, но и о наших ценностях – о том, что мы считали важным, как мы думали, во что верили.
Си говорит о семидесятых: ограниченные ресурсы, доверие инженеру, близость к машине. Java говорит о девяностых: корпоративный мир, портируемость, масштаб. Rust говорит о десятых: кризис безопасности, открытые сообщества, строгость компилятора как защита от человеческих ошибок.
Каждый язык – снимок момента человеческой мысли, материализованный в синтаксисе и семантике.
Код – это культура, скомпилированная в байты.
ЧАСТЬ I: ФИЛОСОФИИ
Глава 1. Манифесты
Существует особый класс текстов, которые определяют язык программирования не меньше, чем его спецификация. Это не документация в привычном смысле – не описание функций и не справочник по синтаксису. Это манифесты: документы, в которых создатели языка пытаются объяснить, почему язык устроен именно так, а не иначе.
Манифест – это застывшая философия. Когда Тим Питерс записал девятнадцать афоризмов, которые мы знаем как Zen of Python, он не просто составил список советов. Он зафиксировал систему ценностей, которая определяла решения Гвидо ван Россума на протяжении десятилетия. Когда Роб Пайк произносил Go Proverbs перед аудиторией Gopherfest, он артикулировал то, что команда Go считала правильным – и, что важнее, то, от чего она сознательно отказалась.
Манифесты редко читают целиком. Программисты цитируют отдельные строки – «Explicit is better than implicit» («Явное лучше неявного»), «Clear is better than clever» («Ясное лучше умного») – как заклинания, не задумываясь о контексте. Но если прочитать эти документы внимательно, в них обнаруживается нечто большее, чем набор максим. В них видна картина мира, которую создатели языка считали правильной.
Три манифеста, три философии: Python с его культом ясности, Ruby с верой в счастье программиста, Go с дисциплиной простоты. Каждый из них – ответ на вопрос о том, как должен думать человек, общаясь с машиной. И ответы получились разными.
1.1. Zen of Python: ясность как ценность
В 1999 году Тим Питерс отправил в рассылку comp.lang.python письмо, которое изменило способ разговора о Python. Он назвал его «The Zen of Python», и письмо содержало девятнадцать коротких утверждений о том, каким должен быть хороший код. Двадцатое место Питерс оставил пустым. Он никогда не объяснил почему, но само это молчание стало частью философии: иногда лучший ответ – отсутствие ответа.
Текст был включён в Python Enhancement Proposal под номером 20 и получил особый статус. В отличие от других PEP, которые предлагают конкретные изменения в язык, PEP 20 не предлагает ничего – он описывает. Это не план действий, а система координат. И в знак признания этого статуса разработчики встроили Zen of Python в сам интерпретатор: достаточно написать «import this», чтобы прочитать его.
«Beautiful is better than ugly. Explicit is better than implicit. Simple is better than complex. Complex is better than complicated.» – «Красивое лучше уродливого. Явное лучше неявного. Простое лучше сложного. Сложное лучше запутанного.»
Первые строки задают тон. Красота здесь не эстетическая категория – это свойство кода, который легко понять. Явность противопоставлена магии: если что-то происходит, читатель кода должен видеть, что именно. Различие между простым и сложным, сложным и запутанным – не игра слов. Простое решение лучше сложного при прочих равных, но сложное решение сложной проблемы лучше, чем запутанное решение, которое притворяется простым.
«Readability counts» – «Читаемость имеет значение».
Эта короткая фраза – возможно, самая важная в документе. Код пишется один раз, читается многократно. Программист, который напишет нечитаемый код ради экономии нескольких символов, украдёт время у всех, кто будет этот код поддерживать, – включая себя через полгода.
«There should be one – and preferably only one – obvious way to do it» – «Должен существовать один – и желательно только один – очевидный способ сделать это».
Эта строка – сознательный контраст с девизом Perl: «There’s more than one way to do it» – «Есть больше одного способа сделать это». Perl гордился тем, что давал программисту свободу выбора. Python занял противоположную позицию: если существует много способов сделать одно и то же, каждый программист выберет свой, и чтение чужого кода превратится в разгадывание головоломки. Один очевидный способ – это не ограничение, а освобождение. Не нужно выбирать, не нужно спорить о стиле, не нужно переучиваться при переходе в новую команду.
Чтобы понять Zen of Python, нужно знать контекст его создания. Гвидо ван Россум начал работу над Python в декабре 1989 года в Центре математики и информатики в Амстердаме. Он искал занятие на рождественские каникулы, и этим занятием стало создание языка.
Но Python не возник из пустоты. Ван Россум участвовал в разработке ABC – образовательного языка, созданного в том же центре. ABC был спроектирован, чтобы научить людей программировать, не отпугивая их. Многие черты Python – значимые отступы, простой синтаксис, интерактивный режим – пришли из ABC. Но ABC никогда не вышел за пределы академии. Ван Россум хотел создать язык с той же философией доступности, но пригодный для реальной работы.
«I had this idea that Python should be easy to learn and easy to read» – «У меня была идея, что Python должен быть лёгким для изучения и лёгким для чтения», – говорил ван Россум в интервью. Лёгкость обучения и лёгкость чтения – не одно и то же, но он стремился к обоим. Лёгкость обучения означала минималистичный синтаксис: меньше специальных символов, меньше исключений из правил, меньше «магии». Лёгкость чтения означала, что код должен выглядеть почти как псевдокод – понятный человеку, который никогда не видел Python.
«I was aiming for a language that would be useful for people who didn’t want to be computer scientists» – «Я стремился к языку, который был бы полезен людям, не желающим становиться учёными-информатиками», – объяснял он в другом интервью. Python задумывался не для профессиональных программистов, а для учёных, системных администраторов, всех, кому нужно автоматизировать рутину, но кто не готов тратить годы на изучение сложных языков.
Эта философия определила множество конкретных решений. Почему в Python нет объявления переменных? Потому что это лишний шаг, который отпугивает новичков. Почему нет фигурных скобок для блоков кода? Потому что отступы и так используются для читаемости – почему бы не сделать их обязательными? Почему нет перегрузки операторов в стиле C++? Потому что это усложняет понимание кода: «a + b» должно означать сложение, а не что-то неожиданное.
«Special cases aren’t special enough to break the rules. Although practicality beats purity» – «Особые случаи не настолько особые, чтобы нарушать правила. Хотя практичность побеждает чистоту».
Вот суть Python в двух строках. С одной стороны – последовательность: не делай исключений из правил ради удобства отдельных случаев. С другой – прагматизм: если правило мешает делу, нарушай его. Это не противоречие, а баланс. Питерс описывает не догму, а инженерное суждение.
Python никогда не был чистым языком. В нём есть множественное наследование, хотя это усложняет понимание кода. В нём есть lambda, хотя Гвидо ван Россум неоднократно сожалел о её синтаксисе. В нём есть глобальная блокировка интерпретатора (GIL), которая мешает параллельному выполнению, – компромисс, принятый ради простоты реализации в эпоху, когда многоядерные процессоры были экзотикой.
Каждое из этих решений можно критиковать. Но в совокупности они создали язык, который стал вторым по популярности в мире. Не потому, что он идеален – потому, что он последователен в своих компромиссах. Python предпочитает читаемость выразительности, простоту мощности, прагматизм чистоте. Zen of Python – это не описание языка. Это описание выборов, которые были сделаны при его создании.
1.2. Ruby Way: счастье программиста
В 1993 году Юкихиро Мацумото, известный в сообществе как Matz, начал работу над языком, который должен был сделать его счастливым. Это не метафора и не преувеличение – Мацумото буквально ставил такую цель.
«I wanted to have fun programming. I wanted to minimize my frustration. I wanted to maximize my joy» – «Я хотел получать удовольствие от программирования. Я хотел минимизировать разочарование. Я хотел максимизировать радость», – объяснял он много лет спустя.
Ruby появился в Японии и долгое время оставался почти неизвестным за её пределами. Первая книга на английском вышла только в 2000 году, через пять лет после публичного релиза. Но когда западный мир наконец открыл Ruby, он обнаружил язык с необычной философией: язык, спроектированный вокруг эмоций программиста.
«Ruby is designed to make programmers happy» – «Ruby создан, чтобы делать программистов счастливыми».
Мацумото повторял эту фразу в сотнях интервью, и с каждым повторением она становилась чем-то большим, чем личное предпочтение, – она становилась манифестом. Что значит «счастье» в контексте языка программирования? Для Мацумото это означало несколько вещей: выразительность, позволяющую записать мысль так, как она приходит в голову; гибкость, не заставляющую бороться с языком; элегантность, приносящую эстетическое удовольствие.
Ruby наследует идеи из множества источников: Perl дал ему выразительность и работу с текстом, Smalltalk – объектную модель, Lisp – метапрограммирование. Но сочетание этих элементов уникально. В Ruby всё является объектом – даже числа, даже nil, даже классы. Это не просто техническое решение, это философское: мир программы однороден, в нём нет «особых случаев».
«I believe people want to express themselves when they program. They don’t want to fight with the language» – «Я верю, что люди хотят выражать себя, когда программируют. Они не хотят сражаться с языком», – говорил Мацумото.
В Ruby можно написать одно и то же многими способами. Это прямая противоположность Python с его принципом «один очевидный способ». Где ван Россум видел хаос и непоследовательность, Мацумото видел свободу и уважение к программисту. Почему язык должен диктовать единственный правильный путь? Пусть каждый выберет тот способ, который кажется ему красивым.









