
Раскопал на Medium интересное эссе про Elixir от разработчика Krzyś. Написано так захватывающе и самобытно, что не смог пройти мимо. Хотел чуть-чуть подсократить, но каждый раздел важен, а терять стиль автора не хочется. Вот тут первая часть, а это — вторая.
IX. Все это уже было: великая ведомость переизобретений
«Любая достаточно сложная конкурентная программа на другом языке содержит самодельную, неформально описанную, медленную и полную ошибок реализацию половины Erlang».
— первое правило программирования Роберта Вирдинга. Он был одним из создателей Erlang, так что ему виднее

Итак, мы подошли к разделу, вынесенному в заголовок: к ведомости.
Потому что, усвоив предыдущие пять разделов, уже невозможно смотреть на схему современной архитектуры без постоянного ощущения легкого дежавю. Не покидает тревожное ощущение, что все это вы уже видели — в статье из девяностых, только набранной более уродливым шрифтом.
Давайте проведем учет как положено — пункт за пунктом.
Микросервисы — озарение, снизошедшее на индустрию примерно в 2014 году. Небольшие независимые изолированные компоненты, которые обмениваются сообщениями, развертываются отдельно и выходят из строя независимо друг от друга.
В BEAM, где все это работает с восьмидесятых, такой компонент называется процессом. Только процесс BEAM занимает килобайты, а не целый контейнер, общается за микросекунды, а не через сетевой запрос по HTTP, и не требует Dockerfile, реестра образов и отдельной платформенной команды.
Мы заново изобрели процесс, но добавили внутрь приложения сетевые задержки, а планировщик заменили счетом от AWS.
Kubernetes — 2014 год. Декларативное описание желаемого состояния, проверки работоспособности, автоматические перезапуски и эскалация сбоев.
То есть дерево супервизоров, формализованное в OTP к 1998 году и переписанное на YAML людьми, которые — я говорю это с любовью, как сертифицированный страдалец от YAML, — не читали диссертацию Армстронга.
Она называется «Создание надежных распределенных систем при наличии программных ошибок». Написана в 2003 году. Доступна бесплатно. И примерно до 2028 года описывает дорожную карту всей вашей платформенной команды.
Service mesh — 2017 год. Прозрачное взаимодействие сервисов, повторные запросы, наблюдаемость за потоками сообщений.
То есть обмен сообщениями, но с большим количеством вендоров. Версии BEAM не нужен сайдкар, потому что сеть сервисов здесь уже встроена в саму среду выполнения.
Событийно-ориентированная архитектура — озарение, которое продолжает нисходить на нас и сегодня. Сервисы реагируют на сообщения из очередей, а не вызываются синхронно.
Каждый процесс BEAM работает по событийной модели с тех времен, когда Великобританией управляла Маргарет Тэтчер. handle_cast — это Kafka для людей, которые хотели получить свои события еще сегодня утром.
Async/await — JavaScript в 2017 году, Rust в 2019-м, рано или поздно — все остальные. Синтаксис, с помощью которого вы вручную отмечаете места, где код должен уступить управление, потому что среда выполнения не сможет вытеснить его самостоятельно — ее приходится вежливо об этом просить.
Этот пункт заслуживает особой нежности.
Async/await — это ручная имитация вытесняющего планировщика. Проблема «цвета функций», правила хорошего поведения для исполнителя, целый жанр статей под заголовком «Почему асинхронный Rust — это сложно» — все это труд по ручному воспроизведению в системе типов того, что вышибала BEAM делает молча, бесплатно и со всеми без исключения.
Здесь мы заново изобрели даже не колесо. Мы заново изобрели ногу — и опубликовали серию руководств по ходьбе. (прим. переводчика: очень смешно)
Возрождение модели акторов — Akka для JVM, Orleans для .NET и библиотека акторов для каждого языка, по которому уже устраивают конференции.
По крайней мере, это прямые заимствования, честно признающие свое происхождение. Хотя переносить модель акторов без приватных куч и вытесняющего планировщика — примерно как перенимать шведский флаг, но не трогать шведскую социал-демократию.
Цвета те же, но где гарантии?
По отдельности каждый пункт можно защитить. Экосистемы, многоязычные команды, границы между организациями — все это действительно есть.
Но прочитайте ведомость целиком — и правило Вирдинга перестанет быть шуткой. И станет диагнозом.
Современный облачно-нативный стек в совокупности представляет собой медленную, растянувшуюся на десятилетия, спроектированную комитетами и стоившую миллиарды долларов повторную реализацию BEAM.
Единственное настоящее нововведение — теперь за нее нужно еще и платить каждый месяц.
Мы не забыли об акведуке — он был на карте. А мы каждый день проезжали мимо него по дороге на завод бутилированной воды.
X. Арифметика WhatsApp
«Дайте мне точку опоры и достаточно длинный рычаг — и я переверну мир».
— Архимед, рассчитывая численность команды

Если предыдущая ведомость показалась вам слишком абстрактной, позвольте предъявить доказательство, которое точно закроет большинство сомнений. Оно написано на языке, которым свободно владеет любое руководство: на языке денег.
В 2014 году, на момент продажи — той самой сделки на 19 миллиардов долларов, о которой вы, возможно, слышали, — WhatsApp обслуживал около 450 миллионов пользователей силами примерно тридцати пяти инженеров.
Не трех с половиной тысяч.
Тридцати пяти человек. И лишь часть из них работала над серверным ядром на Erlang.
Уже в следующем году в источниках фигурировали около 900 миллионов пользователей и по-прежнему лишь порядка пятидесяти инженеров. Точные цифры немного различаются — с такими данными это случается всегда, — но порядок величин никто всерьез не оспаривает. А именно в нем и заключается весь смысл.
На одного инженера приходились десятки миллионов пользователей системы. Тем временем обычная для индустрии численность команды, необходимой для проекта уровня «ура, мы создали чат», легко превышает вместимость первого офиса WhatsApp.
И дело было не в героизме этих 35 инженеров.
Именно ради этого мы разбирали все предыдущие разделы. Это была арифметика.
Миллионы дешевых изолированных процессов. Планировщик, который невозможно лишить ресурсов. Супервизоры вместо ночных вызовов дежурному инженеру. Отдельная сборка мусора для каждого процесса вместо многодневных экспедиций по настройке GC.
Знаменитые цифры из инженерного блога WhatsApp — несколько миллионов TCP-соединений на одном сервере во времена, когда это считалось научной фантастикой, — были показателем той же арифметики, только на уровне сокетов.
Архимедовский рычаг оказался таким длинным потому, что кто-то в Швеции ковал его двадцать лет. WhatsApp оставалось лишь найти точку опоры.
Есть у этой закономерности и современные подтверждения.
Discord вырос до сотен миллионов пользователей, используя Elixir для управления своим ядром реального времени. А там, где требовалась чистая вычислительная мощность, он обращался к NIF на Rust. Помните подсобку нашего вышибалы? Скоро к нему вернемся.
Fly.io управляет своей инфраструктурой с помощью Elixir и рассказывает об этом с добродушным самодовольством людей, чей дежурный телефон молчит.
Иными словами, акведук не просто стоит до сих пор. Им активно пользуются — и их юнит-экономика смущает всех остальных.
XI. Elixir: у акведука появляется нормальная сантехника
«Красота спасет мир».
— Достоевский, рецензируя предложение по новому синтаксису

Но если технология была настолько хороша, почему мир двадцать лет обходил ее стороной?
Причин много — раздел с контраргументами уже выразительно прочищает горло, — но одна из них до жестокости проста: не вышла физиономией.
А при распространении технологий, как и в ресторанном бизнесе, внешний вид важнее содержания. Это несправедливо, но это правда. Мое предыдущее эссе было как раз об этом, поэтому повторяться не буду.
И вот примерно в 2011 году появляется Жозе Валим — участник основной команды Rails, то есть человек, профессионально воспитанный на убеждении, что счастье разработчика — это вполне законное инженерное требование. Он пришел из экосистемы, превратившей синтаксис в язык любви.
Валим искал среду выполнения, способную справиться с будущим многоядерных систем, нашел BEAM и, как я полагаю, пережил примерно тот же момент на кухне, что и я.
Его ответом стал Elixir.
Не новая виртуальная машина. Не форк. Не переписанная с нуля система. Просто новое видение старого акведука.
Те же процессы, тот же OTP, те же гарантии и компиляция в тот же байт-код BEAM. Только теперь — с синтаксисом, который беженец из мира Ruby способен прочитать в первый же день, системой макросов, позволяющей аккуратно расширять язык, и — значение этого трудно переоценить, если вам доводилось жить без таких удобств, — инструментами, которые уважают ограниченность вашей земной жизни.
mix для управления проектами. hex для пакетов. Документация, сама по себе ставшая отдельным жанром.
А затем экосистема сделала то, что превращает язык в тренд: создала убойные приложения, решающие проблемы сегодняшнего дня.
Веб-фреймворк Phoenix превратил фразу «мы держим два миллиона WebSocket-соединений» из темы доклада на главной сцене конференции в обычный пункт из списка возможностей.
А LiveView заслуживает отдельного личного признания.
С помощью LiveView можно создавать насыщенные интерактивные интерфейсы реального времени на сервере и передавать их через WebSocket — практически без JavaScript. Сервер хранит состояние — разумеется, внутри процесса, сравнивает состояния DOM и отправляет браузеру только минимальные изменения.
Для человека, на странице «О себе» которого JavaScript-усталость указана как хроническое заболевание, это не просто возможность фреймворка.
Это паллиативная помощь.
Когда я впервые увидел, как форма проверяет данные через сеть без единой написанной мной строки JavaScript, то испытал чувство, которое могу описать только так: с меня сняли проклятие, к которому я уже настолько привык, что перестал его замечать.
Но главный вывод глубже. Elixir доказывает, что проблема никогда не заключалась в самом транспорте.
Двадцать лет фраза «Erlang потрясающий, но какой-то странный» звучала безапелляционно. А затем кто-то сменил обивку в салоне: тот же двигатель, но новые кожаные сиденья — и вот уже о нем рассказывают на главных сценах конференций.
Это одновременно триумф вкуса Валима и обвинение в адрес всех нас. Потому что оно подтверждает самый неприятный пункт нашей ведомости.
Мы отвергли не воду из акведука.
Мы всего лишь посмотрели на шрифт, которым была написана табличка, и ушли.
XII. Gleam: первая доза
«Первая доза бесплатно».
— каждый наркодилер и каждый язык со статической типизацией

Раз уж это эссе начиналось как признание, честно расскажу и о своем опыте: я тоже отвернулся от этой неказистой физиономии.
Я пришел через Gleam.
Gleam — новейший обитатель BEAM: небольшой язык со статической типизацией. Настоящая система типов Хиндли — Милнера, качественный товар, наследие OCaml, в котором мое сердце, прикипевшее к Rust, с первого взгляда распознает знакомый паттерн. Он компилируется для той же среды выполнения, а его дружелюбный компилятор объясняет свои возражения как терпеливый коллега, а не как невыспавшийся таможенник.
Язык молодой, намеренно компактный и красивый — так, как бывают красивы хорошо спроектированные небольшие вещи.
Для человека, пришедшего из Rust, знакомство с Gleam напоминает встречу с дальним родственником на семейном празднике: алгебраические типы данных, исчерпывающий case, отсутствие nil. Мебель знакомая, дом чужой. (прим. переводчика: референс — «Ирония судьбы»)
И именно в этом, независимо от намерений создателей, заключается роль Gleam в экосистеме — это первая доза.
Типизированная прихожая, через которую заходят адепты статической типизации — люди, которые ни за что не прикоснулись бы к динамическому языку с литургическими точками в конце выражений. Они осматриваются, устраиваются поудобнее, а затем начинают задавать опасные вопросы вроде: «Подождите, а что такое OTP?»
В моем случае маршрут выглядел так:
Gleam → блог LambdaClass → Elixir → Erlang, чтобы читать надписи на руинах в оригинале.
И вот мы здесь, несколько тысяч слов спустя, разговариваем сами с собой на кухне.
Справедливости ради ситуация с типизацией в BEAM действительно меняется. И слово «меняется» даже преуменьшает происходящее, потому что перед нами не слайд с планами на будущее, а уже работающая функциональность.
В Elixir развивается теоретико-множественная система типов, основанная на исследованиях специалистов по теории типов Джузеппе Кастаньи и Гийома Дюбока и активно продвигаемая самим Валимом. Первые ее элементы уже встроены в компилятор: версии 1.17 и 1.18 вышли с постепенным выводом типов и предупреждениями, которые находят реальные классы ошибок в обычном коде — без обязательных аннотаций.
Редкий случай, когда сотрудничество с академическими исследователями приходит не в виде обещания когда-нибудь потом, а в ближайшем релизе.
Поэтому старое противопоставление «гениальная среда выполнения, но никаких типов» исчезнет не когда-нибудь, а прямо сейчас.
Тем временем Dialyzer, заслуженный инструмент экосистемы для success typing, занимает странную нишу: он одновременно незаменим и при этом никому особо не нравится.
Dialyzer проверяет типы так, как разочарованный родственник оценивает ваши жизненные решения: достаточно точно, но уже слишком поздно. И с вот этой особенной интонацией.
Если вы пришли из моей серии о Rust и ищете самый пологий вход во все, о чем рассказывает это эссе, начните с Gleam ради комфортного синтаксиса, но не останавливайтесь на нем.
Сокровище — не язык.
Сокровище — то, что под капотом этой машины.
XIII. Контраргумент, который я не могу полностью отбросить
«Признак первоклассного ума — способность одновременно удерживать в голове две противоположные идеи и при этом сохранять способность действовать».
— Фрэнсис Скотт Фицджеральд, рецензируя мой технологический радар

Традиция есть традиция: настало время поспорить с собственным эссе.
И на этот раз у контраргументов прорезались острые зубы. Акведук зарос не просто так. Римляне строили акведуки там, где позволял рельеф. Никто не прокладывал их через болото.
Поэтому давайте честно осмотрим это болото.
BEAM — гений координации и посредственный вычислитель. Она управляет вводом-выводом, соединениями и сбоями лучше практически всего существующего, но перемалывает числа.
Сложная математика, обработка изображений, инференс моделей машинного обучения — не ее территория.
Ответ экосистемы — NIF, нативный код, причем все чаще Rust через Rustler. Действительно элегантный союз: Rust защищает память там, где не достает BEAM, а BEAM защищает процессорное время там, где Rust этого не делает. Именно на таких решениях LambdaClass и строит свой бизнес.
Но типы опоздали на тридцать лет. Да, теоретико-множественная система уже появляется, есть Gleam и Dialyzer. Но в течение трех десятилетий большие вещи в этой экосистеме строились на динамической типизации и дисциплине.
Если вы считаете типы несущей частью документации, значит, все годы своего становления экосистема была структурно недокументирована.
Это не оскорбление, а осознанный компромисс основателей. Они работали в области, где среда выполнения должна была ловить то, чего не заметил компилятор.
Но я не стану притворяться, будто не замечаю этого.
Рынок специалистов здесь размером с джаз-клуб.
Прекрасный джаз-клуб — возможно, с самой высокой концентрацией великолепных музыкантов во всей индустрии. Но попробуйте объяснить техническому директору, что собираетесь расширять команду на языке, вся конференция которого помещается в одном отеле.
Притяжение экосистем — настоящая сила. В мирах JVM и JavaScript найдется библиотека для чего угодно, включая несколько библиотек для того, что вообще не должно существовать.
Выбрать BEAM — значит иногда самостоятельно писать нужный клиент. В индустрии, которая уже и забыла, что так можно.
У распределенного Erlang есть звездочка.
Встроенная кластеризация предполагает полносвязную сеть узлов, которые доверяют друг другу и работают в дружелюбном окружении. Эта модель родилась во времена, когда слова «компьютерная сеть» означали одно здание в Стокгольме.
Внутри доверенного кластера она великолепна. Но в открытом и враждебном интернете — наивна.
В реальных системах поверх нее добавляют современные транспортные механизмы и границы безопасности. Это окей, но также значит, что самый эффектный фокус — «смотрите, процессы общаются между машинами, будто никакой сети вообще нет!» — поставляется мелким шрифтом с примечаниями.
И наконец, метааргумент — тот самый, который не позволяет мне окончательно увлечься собственной правотой.
Возможно, индустрия обошла акведук не по глупости. Возможно, так проявились ее реальные предпочтения.
Kubernetes не зависит от языка. Дерево супервизоров хочет, чтобы все приложение жило внутри одной среды выполнения.
Микросервисы позволяют тысяче команд на тысяче языков выпускать изменения независимо друг от друга. А цельность BEAM одновременно означает и монокультуру.
Возможно, мы платили наценку за бутилированную воду не ради самой воды, а за право не соглашаться друг с другом по поводу устройства водопровода.
Это организационная свобода, купленная чудовищно высокой технической ценой. И закон Конвея в любом случае рано или поздно выставил бы нам за нее счет.
Я по-прежнему думаю, что мы чудовищно переплатили.
Но признаю: мы все-таки что-то приобрели.
Итак, примерно 70% — в пользу основной идеи и 30% — в пользу болота. Замеры проведены после кофе, который, как знают мои постоянные читатели, добавляет моей уверенности десять процентных пунктов.
Даже Ericsson — и это, возможно, лучшее примечание во всей истории — в 1998 году ненадолго запретила использовать Erlang внутри компании. Примерно тогда же язык открыли для внешнего мира.
Собор изгнал собственных архитекторов.
Так что, осторожничая с окончательным выводом, я как минимум нахожусь в достойной компании: даже место, где родилась эта технология, не могло решить, что о ней думать.
XIV. Синусоида: версия с веткой
«Ты можешь выписаться когда угодно, но уйти не сможешь никогда».
— The Eagles о долгоживущих ветках

По условиям негласного договора постоянным читателям полагается синусоида. Но в этом эссе знакомый мотив принимает форму, которая тревожит меня сильнее обычного маятника.
Потому что маятник предполагает, что рано или поздно мы качаемся обратно.
А эта история устроена страннее: это ветка, которую я так и не смерджил.
Представьте всю индустрию в виде одного гигантского репозитория. Где-то в 1986 году небольшая шведская команда создала ветку feature/reliability-first и просто продолжила в ней работать, пока main стремительно неслась сначала к объектам, потом к вебу, а затем к облакам.
Ветку никто не забрасывал. Каждый год появлялись новые коммиты, код выкатывался в продакшен, а индикатор CI оставался зеленым четыре десятилетия подряд.
Тем временем main, не вполне признавая само существование параллельной ветки, периодически хватала из нее отдельные коммиты.
Модель акторов — черрипикнута в Akka, встречена овациями.
Супервизоры и автоматическое восстановление желаемого состояния — перенесены в Kubernetes, получили три конференции.
Неизменяемые данные — перенесены практически во все технологии и представлены как открытие функционального ренессанса.
Изоляция через обмен сообщениями — оказалась в микросервисах и породила целую консалтинговую индустрию.
Каждый такой cherry-pick появляется в main под громкие аплодисменты в честь очередной инновации. И каждый раз git blame для исходного фрагмента показывает одни и те же три имени и временную метку из Стокгольма.
Это шутка.
Но от нее тревожно, хочу оставить эту тревогу и у вас — занозой в неудобном месте.
Синусоида, о которой я обычно пишу, — GUI и CLI, толстые и тонкие клиенты, хайп и откат после него — по крайней мере видима. Все замечают движение маятника, и мы спорим о нем на конференциях.
С этим форком все иначе.
Это целая параллельная линия разработки, которую мейнстрим умудрялся десятилетиями не замечать. Не опровергать. Не изучить и отвергать. Просто… не видеть.
Так же, как не замечаешь акведук с автострады.
И это подводит нас к по-настоящему тревожному вопросу — тому самому, вокруг которого вся эта серия кружит на разных высотах:
Что еще прямо сейчас находится в неслитой ветке?
Как выглядит аналог Erlang в 2026 году — немодный, проклятый неудобным синтаксисом, но при этом незаметно предлагающий правильный ответ на проблему, из-за которой в 2040-м мы все будем в панике?
Что за технология сегодня поддерживается одиннадцатью людьми, пока все остальные отмахиваются от нее просто потому, что им не зашел вайб?
Статистически она существует.
Статистически я уже успел презрительно над ней усмехнуться.
XV. Чему все это нас учит, кроме смирения. Том III
«Жизнь можно понять, только оглядываясь назад, но жить ее приходится вперед».
— Кьеркегор, перед ретро

Соберу наконец все нити воедино. За три случайно связанных между собой эссе они сплелись в узор, которого я изначально не планировал.
В первом эссе этой невольной трилогии я говорил, что хайп — это признание сложности. Во втором — хотя с тех пор прошло уже несколько эссе — оплакивал акведуки и утраченные знания.
Нынешнее эссе усложняет обе идеи, потому что здесь знания никогда не были утрачены.
Диссертацию можно скачать. Среду выполнения — установить через apt-get. Разработчики отвечают на сообщения.
В этом случае сломалась не передача, а восприятие. Причиной стала мода — а мода, как мы уже подробно установили, представляет собой систему верований + маркетинг.
Erlang проиграл девяностые и нулевые не из-за себя, а из-за литургии: не те мантии, не тот приход, проповеди на шведском диалекте Prolog.
Вокруг него не было хайпа. И если хайп значит, что проблема пугает, то отсутствие хайпа вокруг OTP говорит о другом: решение оказалось слишком скучным, чтобы его бояться.
Ни демона, которого нужно изгнать. Ни культа, к которому можно примкнуть. Ни сюжетной арки.
Просто дерево супервизоров, которое сорок лет молча перезапускает упавшие процессы.
Из фразы «оно работает, а потом продолжает работать» не получится доклада для главной сцены конференции. Как выяснилось, наша профессия способна пройти даже мимо работающего чуда, если оно не пугает нас и не льстит нам.
Наше внимание хочет драмы.
А надежность — убивает драму.
И здесь на свое место встает последний элемент всей серии: хранителям замысла, о которых шла речь еще в первом эссе, нужно добавить еще один пункт в должностную инструкцию.
Недостаточно знать, что должно существовать и зачем.
Кто-то должен поддерживать карту того, что уже существует, — в том числе немодные провинции.
Потому что самая дорогая фраза в разработке — не «мы не знаем, как это сделать». Обычно мы знаем. Кто-то уже описал решение в 2003 году, в Стокгольме, перед диссертационной комиссией.
Самая дорогая фраза в разработке — «у нас так не принято».
Ее произносят, проезжая мимо акведука по дороге на завод бутилированной воды, когда счет за строительство уже лежит на почте.
Последнюю главу убрал, так как в ней нет пользы — только лирика. Что думаете, коллеги? Я прочитал не с первого раза, но не жалею о потраченном времени. Побольше бы таких эссе.