Раздел 27 · Gleam на практике

Введение в Gleam, язык на BEAM

junior~30 мин

открытый урокЭтот раздел читается без входа. Войди, чтобы отмечать прогресс, вести заметки и решать задачи в редакторе. войти

Введение в Gleam, язык на BEAM

Открываем серию по Gleam. Это маленький типизированный язык, который собирается в Erlang-байткод и в JavaScript из одного исходника. Внутри: акторы из BEAM, система типов на уровне ML, синтаксис как у TypeScript. Эта глава знакомит с миром, дальше пишем код.

Сцена, два мира сходятся

Представь шкалу. На одном конце сидит Erlang/Elixir: акторы, supervisor-деревья, миллионы лёгких процессов, девять девяток uptime. Системы вроде WhatsApp обслуживают два миллиарда пользователей на одной такой VM. Но типы появляются только в рантайме: компилятор не ловит опечатку в имени поля, не помешает сложить число с атомом.

На другом конце сидят ML-семейные языки: Haskell, OCaml, Elm. Алгебраические типы данных, parametric polymorphism, exhaustive pattern matching. Компилятор отказывается собирать код, в котором не разобраны все варианты. Но рантайм у каждого свой, и Process-овская модель Erlang там не растёт.

Gleam стоит ровно посередине. Тот же BEAM снизу, та же дисциплина типов сверху. Без классов типов, без макросов, без GADT, ничего лишнего. Один стиль именования, одна каноничная форма функции.

Чем Gleam цепляет

  • Безопасность типов, ошибки ловятся компилятором, а не пользователем в продакшене.
  • BEAM под капотом, миллионы конкурентных процессов, supervisor-деревья, hot-reload, всё то же, что у Erlang.
  • Намеренная простота, минимум синтаксиса, единый стиль через встроенный gleam format.
  • Двойной таргет, тот же код собирается в Erlang-байткод (сервер) и в JavaScript (браузер и Node).
  • Совместимость, через FFI доступна вся экосистема Hex (Erlang плюс Elixir плюс родной Gleam).

BEAM: виртуальная машина, проверенная временем

BEAM (Bogdan/Björn’s Erlang Abstract Machine), виртуальная машина, созданная в Ericsson для телекоммуникаций. Её ключевые свойства:

  • Лёгкие процессы, миллионы конкурентных процессов в одной VM, каждый с собственной кучей.
  • Изоляция сбоев, падение одного процесса не затрагивает другие.
  • Распределённость, процессы общаются по сети прозрачно.
  • Hot-reload, обновление кода без остановки системы (для Gleam пока не штатно).

На BEAM работают системы, обслуживающие сотни миллионов пользователей:

СистемаМасштаб
WhatsApp2 млрд пользователей, ~50 инженеров
DiscordМиллионы конкурентных подключений
RabbitMQОдин из самых популярных брокеров сообщений
EricssonТелекоммуникации с 99.9999999% uptime

Gleam компилируется в Erlang-байткод и получает все эти свойства бесплатно. Код на Gleam вызывает Erlang- и Elixir-библиотеки напрямую, без обёрток и накладных расходов.

Двойной таргет

У Gleam есть еще одно полезное свойство: один и тот же код компилируется в Erlang (для сервера) и в JavaScript (для браузера и Node.js).

              ┌─── Erlang (BEAM) ───► сервер, CLI, IoT
gleam build ──┤
              └─── JavaScript ──────► браузер, Node.js

А для переключения между таргетами достаточно изменить одну строку в gleam.toml:

target = "erlang"   # или "javascript"

Стандартная библиотека Gleam работает на обоих таргетах. Для платформо-специфичного кода используется FFI, вызов Erlang- или JavaScript-функций из Gleam-кода.

Философия Gleam

Gleam, намеренно минималистичный язык. Его создатель Louis Pilfold следует принципу: если фичу можно не добавлять, её не добавляют.

В Gleam нет:

  • Классов типов (type classes)
  • Макросов
  • GADTs и зависимых типов
  • Исключений (в привычном смысле)
  • REPL
  • Перегрузки операторов
  • Неявных приведений типов

Это не ограничение, а осознанный выбор. Каждая строка кода на Gleam читается однозначно: нет скрытой диспетчеризации, нет магии макросов, нет неявных преобразований. Код делает ровно то, что написано.

Дружелюбные ошибки

Gleam известен исключительно понятными сообщениями об ошибках. Компилятор не просто говорит “type mismatch”, он объясняет, что пошло не так, и часто предлагает исправление:

error: Type mismatch
  ┌─ src/main.gleam:4:17
  │
4 │   string.length(42)
  │                 ^^

Expected type:
    String

Found type:
    Int

Hint: try using `int.to_string` to convert the value.

Компилятор указывает точную строку и столбец ошибки, показывает ожидаемый и найденный тип, и сразу предлагает исправление. Это делает работу с Gleam особенно приятной для новичков.

Hex, единая экосистема

Gleam использует Hex, менеджер пакетов, общий с Erlang и Elixir. Это означает доступ к Erlang-библиотекам напрямую, а также к растущей экосистеме собственных Gleam-пакетов: Wisp (веб), Lustre (фронтенд), Mist (HTTP-сервер) и многие другие. Подробнее о совместимости с BEAM-экосистемой, в главе 8.

Сравнение с другими языками

GleamElmRustElixirHaskellOCaml
Статическая типизация✓✓✓✗✓✓
BEAM✓✗✗✓✗✗
Простота✓✓✓✗✓✗✗
Конкурентность (акторы)✓✗✗✓✗✗
JS-таргет✓✓✗✗✓*✓*
Зрелая экосистемаРастётСредняя✓✓✓✓✓

* Haskell компилируется в JS через GHCJS/Asterius, OCaml, через js_of_ocaml/Melange. Однако в обоих случаях это отдельные инструменты, а не встроенная возможность компилятора. В Gleam и Elm JS-таргет, штатный режим работы.

  • Elm, ближайший родственник по философии (типы + простота), но работает только в браузере
  • Rust, похожий подход к безопасности, но другой уровень сложности и нет BEAM
  • Elixir, тот же BEAM, но без статических типов
  • Haskell/OCaml, мощные системы типов, есть JS-таргеты через сторонние инструменты, но нет BEAM-конкурентности

Маршрут серии

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

#УрокУровень
01Введение в Gleam (этот)J
02gleam new и базовые типыJ
03Функции, пайплайны и замыканияJ
04ADT, pattern matching, List и DictM
05Рекурсия, свёртки, Result и OptionM
06Строки, BitArray и стандартная библиотекаM
07Parse, don’t validate. Opaque и phantomMS
08Erlang FFI: @external, atoms, ETSMS
09JavaScript FFI и target = javascriptM
10OTP, акторы, supervisor, let it crashMS
11Тестирование: gleeunit, qcheck, birdieM
12Веб на Wisp: запрос-ответ, middlewareMS
13Lustre, TEA-архитектура в браузереMS
14Куда дальше: экосистема BEAMJ
15Финальный проект, Telegram-бот на TelegaS

Базовый блок, уроки 02 по 07, лучше читать подряд. Дальше уроки относительно независимы: можно пойти в OTP (10) и бот (15), а можно сразу в Lustre (13).

Как пользоваться материалом

Каждый урок устроен одинаково:

  • Прозой объясняется одна концепция.
  • Концепция сразу показывается куском кода, который реально собирается через gleam build.
  • В конце урока стоят упражнения (frontmatter homework и тики <Exercise> в тексте), они отмечаются прямо на странице.
  • Связанные темы доступны через <Term>-тултипы (наведи мышкой) и сноски на соседние уроки.

Что нужно от тебя: установленные gleam и erlang/otp плюс желание запускать gleam test после каждой главы. Опыт ФП не требуется, но если ты прошёл 02-cs и 04-ts, многое уляжется быстрее.

Что попробовать прямо сейчас

Полезные ссылки

Итог

Gleam, молодой, но быстро растущий язык. Берёт надёжность ML-системы типов и промышленную конкурентность BEAM, остаётся простым: весь синтаксис можно выучить за выходные. Если ты уже знаешь TypeScript и читал про акторов, у тебя уже половина модели.

Следующий урок, ставим компилятор, собираем первый проект и трогаем базовые типы.