Erlang — это не просто язык программирования, это целая экосистема, созданная для построения систем, которые должны работать вечно. Разработанный компанией Ericsson для телекоммуникационных коммутаторов, требующих феноменальной отказоустойчивости и параллелизма, Erlang переносит эти принципы в мир современных распределенных и высоконагруженных приложений. Если ваша задача — создать чат-сервер, систему обмена сообщениями в реальном времени, блокчейн-ноду или бэкенд для онлайн-игры, где важна одновременная работа миллионов соединений, Erlang (и его современный наследник Elixir) — это мощный кандидат. Данная инструкция проведет вас через основы синтаксиса, ключевые концепции и покажет их в действии на практических примерах.
Шаг 1: Установка и "Hello, World!". Установите Erlang/OTP с официального сайта. После установки откройте оболочку Erlang, набрав в терминале `erl`. Вы окажетесь в интерактивной среде (shell). Для выхода используйте `Ctrl+C`, затем `a`. Давайте сразу напишем первую программу. Создайте файл `hello.erl` со следующим содержимым:
-module(hello).
-export([start/0]).
start() ->
io:format("Hello, World!~n").
Модуль (`-module`) должен называться так же, как файл. Директива `-export` указывает, какие функции доступны извне модуля (здесь функция `start/0`, где 0 — количество аргументов). Символ `->` отделяет объявление функции от ее тела, а `~n` — это символ новой строки. Чтобы скомпилировать и запустить, в оболочке выполните:
c(hello). % компиляция
hello:start(). % вызов функции
Шаг 2: Основы синтаксиса и неизменяемость. В Erlang все данные неизменяемы (immutable). Переменные начинаются с заглавной буквы: `X = 10.` Присваивание (`=`) — это на самом деле сопоставление с образцом (pattern matching). Если `X` уже связана со значением 10, то `X = 10.` будет успешно, а `X = 20.` вызовет ошибку. Списки определяются квадратными скобками: `List = [1, 2, 3].` Кортежи (tuples) — фигурными: `Point = {x, 5, y, 12}.` Атомы — это константы, чье имя является их значением (начинаются со строчной буквы или в кавычках): `ok, error, my_atom.`
Шаг 3: Функции и сопоставление с образцом. Мощь Erlang раскрывается в определении функций через сопоставление с образцом. Рассмотрим классический пример вычисления факториала:
-module(math_utils).
-export([factorial/1]).
factorial(0) -> 1; % Базовый случай
factorial(N) when N > 0 -> N * factorial(N - 1).
Здесь одна функция `factorial/1` определена с двумя "клаузами" (clauses). Erlang последовательно пытается сопоставить аргумент вызова с образцами: `factorial(0)` или `factorial(N)`. Охранное выражение `when N > 0` добавляет дополнительное условие. Вызов `math_utils:factorial(5).` вернет 120.
Шаг 4: Конкурентность — процессы и обмен сообщениями. Сердце Erlang — легковесные процессы (не потоки ОС!). Они изолированы, общаются только через асинхронную передачу сообщений. Создадим два процесса, которые обмениваются приветствиями:
-module(process_demo).
-export([start/0, ping/2, pong/0]).
ping(0, PongPid) ->
PongPid ! finished, % Отправка сообщения 'finished' процессу Pong
io:format("Ping finished~n");
ping(N, PongPid) ->
PongPid ! {ping, self()}, % Отправка сообщения с кортежем и своим PID
receive
pong ->
io:format("Ping received pong~n")
end,
ping(N - 1, PongPid).
pong() ->
receive
finished ->
io:format("Pong finished~n");
{ping, PingPid} ->
io:format("Pong received ping~n"),
PingPid ! pong, % Отправка ответа 'pong' процессу Ping
pong() % Рекурсивный вызов для ожидания следующего сообщения
end.
start() ->
PongPid = spawn(process_demo, pong, []), % Запуск процесса pong
spawn(process_demo, ping, [3, PongPid]). % Запуск процесса ping с аргументами
Оператор `!` отправляет сообщение. `receive ... end` блокирует процесс до получения сообщения, соответствующего одному из шаблонов. `self()` возвращает идентификатор текущего процесса (PID). `spawn` создает новый процесс.
Шаг 5: Обработка ошибок и философия "Let it crash". В Erlang не пишут защитный код на каждом шагу. Процессы настолько легковесны, что их можно просто перезапускать. Супервизоры (Supervisors) — это специальные процессы, которые следят за другими процессами (рабочими) и перезапускают их по заранее заданной стратегии в случае падения. Это позволяет создавать иерархии отказоустойчивых приложений. Само приложение собирается в OTP-приложение (OTP Application) — стандартный способ упаковки кода, супервизоров и конфигурации.
Заключение: Erlang требует смены парадигмы мышления. Вы думаете не в терминах потоков и блокировок, а в терминах изолированных процессов, обменивающихся сообщениями, и стратегий их перезапуска. Начав с простых примеров, вы постепенно освоите мощь OTP и сможете создавать системы, которые остаются работоспособными даже при частичных отказах, что является золотым стандартом в разработке backend-сервисов высокой доступности.
Разбор Erlang: пошаговая инструкция с примерами кода для начинающих
Пошаговое введение в язык программирования Erlang, охватывающее установку, базовый синтаксис, неизменяемость, функции, сопоставление с образцом, легковесные процессы, обмен сообщениями и философию отказоустойчивости "Let it crash" с наглядными примерами кода.
28
3
Комментарии (15)