Перейти к основному содержимому

Elixir — итоги

Разработчику Аналитику Тестировщику Архитектору Инженеру

Кратко — что стоит унести из раздела "Elixir". Если пункт кажется туманным — откройте указанную главу или оглавление.


FAQ — Часто задаваемые вопросы

Типичные сбои и ситуации, с которыми сталкиваются новички после раздела. Здесь — что делать и где копать в главах.

Вопрос. mix deps.get падает с ошибкой hex package или timeout.

Ответ. Проверьте сеть, версию Elixir/OTP (elixir -v), синтаксис mix.exs. За корпоративным proxy настройте HTTP_PROXY; очистите _build и deps при битом кэше. Подробнее здесь — первая программа.

Вопрос. ** (MatchError) no match of right hand side value — строка выглядит нормальной.

Ответ. Оператор = — pattern match, а не присваивание как в C. Форма слева должна совпасть со значением справа; для перезаписи в IEx используйте повторное binding или var = expr в новом scope. Подробнее здесь — основы, типы.

Вопрос. Map.get(map, :key) работает, а map.key — nil, хотя ключ "есть".

Ответ. Атом :key и строка "key" — разные ключи. JSON из Jason по умолчанию — строки; struct — атомы. Приведите ключи к одному виду. Подробнее здесь — типы, приложения.

Вопрос. Создал атом из пользовательского ввода — сервер упал по memory.

Ответ. Атомы не собираются GC; String.to_atom/1 на чужих строках — вектор DoS. Используйте String.to_existing_atom/1 или ключи-строки. Подробнее здесь — типы, приложения.

Вопрос. GenServer.call зависает навсегда — timeout не срабатывает.

Ответ. Укажите GenServer.call(pid, msg, timeout); если процесс занят бесконечной работой в handle_call, timeout лишь на стороне клиента. Тяжёлую работу выносите в Task. Подробнее здесь — функции и процессы.

Вопрос. Почтовый ящик процесса растёт — память утекает "в сообщения".

Ответ. Процесс не успевает обрабатывать receive или отправитель шлёт быстрее, чем consumer. Добавьте back-pressure, :gen_server cast vs call, мониторинг :erlang.process_info(pid, :message_queue_len). Подробнее здесь — архитектура BEAM, процессы.

Вопрос. Supervisor перезапускает child в бесконечном цикле — логи засыпаны ошибками.

Ответ. Стратегия :one_for_one с permanent child будет рестартить при любой ошибке. Исправьте причину падения; временно :temporary для отладки; используйте :max_restarts и :max_seconds. Подробнее здесь — архитектура BEAM.

Вопрос. В IEx многострочный paste даёт синтаксическую ошибку.

Ответ. Используйте #iex.break или paste mode (iex --erl "-kernel shell_history enabled"), либо сохраните код в .exs и import_file. Heredoc в IEx требует аккуратных """. Подробнее здесь — первая программа.

Вопрос. ~c"abc" vs "abc" — charlist и string, функция ожидает другое.

Ответ. Строки — UTF-8 binary; charlist — список codepoints. Старые Erlang API ждут charlist; современный Elixir — binaries. Явно to_string / String.to_charlist. Подробнее здесь — типы.

Вопрос. Enum.map на огромном файле — OOM, хотя "map же ленивый".

Ответ. Enum материализует коллекцию; для потоков — Stream и поэтапный Enum.reduce. Подробнее здесь — функции, приложения.

Вопрос. Сразу открыли Phoenix — не понимаю Router, Endpoint, контексты.

Ответ. Phoenix опирается на Mix, процессы, Plug. Пройдите основыPlug в приложенияхархитектуру BEAM, затем генератор mix phx.new. Подробнее здесь — оглавление.

Вопрос. Node.connect не соединяет два узла на одной машине.

Ответ. Нужны одинаковые cookie и флаги --name / --sname, открытые порты EPMD (4369). Firewall блокирует distribution ports. Подробнее здесь — архитектура BEAM.

Вопрос. "BEAM использует тысячи OS-потоков" — так ли это?

Ответ. Легковесные процессы BEAM — не OS threads; планировщик preemptive на N scheduler threads ≈ числу ядер. Миллионы процессов — нормальная модель. Подробнее здесь — архитектура BEAM.

Вопрос. FunctionClauseError — "no function clause matching".

Ответ. Ни одна головка функции не подошла под аргументы. Добавьте catch-all clause, проверьте типы (atom vs string), guards when. Подробнее здесь — функции, управление.

Вопрос. with без else — при ошибке непонятный match error.

Ответ. Добавьте ветку else для {:error, reason} или используйте with ... <- ..., do: ..., else: .... Подробнее здесь — управление, приложения.

Вопрос. Task.async упал — упал и родительский процесс.

Ответ. По умолчанию task linked. Используйте Task.Supervisor, Task.async_stream с :trap_exit, или Task.start без link для изоляции. Подробнее здесь — процессы.

Вопрос. Jason.decode! с keys: :atoms на внешнем JSON — опасно?

Ответ. Да: атомы из внешних ключей — риск и утечка памяти. Для API используйте keys: :strings и явное маппирование. Подробнее здесь — приложения.

Вопрос. Plug/Cowboy: "port already in use" на 4000.

Ответ. Предыдущий iex -S mix или phx.server не остановлен. Найдите процесс (netstat / диспетчер задач), смените port: в конфиге. Подробнее здесь — приложения.

Вопрос. mix run — application не стартует, "already started" или наоборот silent exit.

Ответ. Проверьте application callback в mix.exs, mod: {App, []} и supervision tree. Для скриптов без OTP используйте mix run --no-start. Подробнее здесь — архитектура BEAM.

Вопрос. Как обновить вложенное поле в map без мутации?

Ответ. put_in / update_in / get_and_update_in с Access behaviour: update_in(user, [:profile, :name], &String.upcase/1). Подробнее здесь — типы.

Вопрос. send vs GenServer.call — когда что?

Ответ. send — асинхронно, без ответа; call — синхронный запрос-ответ с back-pressure. Для stateful сервисов предпочитайте GenServer API. Подробнее здесь — процессы.

Вопрос. Hot code reload на prod — Elixir "сам обновит без даунтайма"?

Ответ. OTP позволяет release upgrade, но это регламентированный процесс (distillery/relx, migrations, state). Не magic — нужна дисциплина версий и supervision. Подробнее здесь — архитектура BEAM.

Вопрос. Elixir и Erlang — нужно учить Erlang отдельно?

Ответ. Elixir компилируется в BEAM bytecode; interop с Erlang-модулями прямой (:crypto, :gen_tcp). Синтаксис другой, OTP общий. Подробнее здесь — история, основы.

Вопрос. Logger заливает консоль — как уменьшить шум?

Ответ. В config/config.exs задайте level: :warning для :logger; в dev используйте Logger.configure/1. Не оставляйте debug в hot path. Подробнее здесь — архитектура.

Вопрос. ExUnit async test падает только в полном прогоне — race?

Ответ. @tag :async требует изоляции (нет shared ETS, global name, одного файла). Уберите async или используйте sandbox для БД. Подробнее здесь — приложения.

Вопрос. Pipe |> ломается на if или case — "undefined function".

Ответ. Pipe подставляет первым аргументом; макросы и special forms нельзя pipe'ить напрямую. Оберните в анонимную функцию или используйте then/2. Подробнее здесь — основы, управление.

Вопрос. Пришёл из Ruby — синтаксис похож, но "не магия" не работает.

Ответ. Elixir — immutable + pattern matching; нет open classes и monkey patch. Переучите мышление на явные контракты {:ok, _} / {:error, _}. Подробнее здесь — основы, типы.

Вопрос. Elixir с нуля — как начать учить язык?

Ответ. Установите Elixir + Erlang, запустите iex, пройдите pipe и pattern matching. Маршрут — первая программаосновы. Подробнее здесь — оглавление.

Вопрос. Elixir vs Erlang — в чём разница?

Ответ. Оба на BEAM; Elixir — современный синтаксис, macros, tooling (Mix, Hex). Erlang-модули вызываются как :module.fun. Подробнее здесь — история, основы.

Вопрос. Phoenix framework tutorial — с чего начать веб на Elixir?

Ответ. Сначала Mix, процессы, Plugприложения, BEAM; затем mix phx.new. LiveView — после базового HTTP. Подробнее здесь — оглавление.

Вопрос. Как установить Elixir на Windows 11 / Ubuntu?

Ответ. Windows — installer с elixir-lang.org; Linux — apt/dnf или asdf. Нужен Erlang/OTP (elixir -v показывает оба). Подробнее здесь — первая программа.

Вопрос. Elixir pattern matching tutorial — как работает =?

Ответ. = сопоставляет форму, не присваивает как в C: {ok, val} = {:ok, 42}. Несовпадение — MatchError. Подробнее здесь — основы, типы.

Вопрос. GenServer Elixir example — зачем нужен?

Ответ. OTP-процесс с состоянием и стандартными callback (handle_call/cast). Серверы, кэши, воркеры. Подробнее здесь — функции и процессы, BEAM.

Вопрос. Supervisor Elixir strategy one_for_one — что это?

Ответ. При падении child перезапускается только он (:one_for_one). Другие стратегии — :one_for_all, :rest_for_one. Подробнее здесь — архитектура BEAM.

Вопрос. Elixir pipe operator |> example?

Ответ. "hello" |> String.upcase() |> String.reverse() — первый аргумент следующей функции. Идиома data pipeline. Подробнее здесь — основы.

Вопрос. Elixir vs Ruby — похож ли синтаксис?

Ответ. Внешне похож (do/end, |>), но Elixir immutable, без monkey patch, процессы BEAM вместо GIL. Подробнее здесь — основы, типы.

Вопрос. Elixir vs Go для backend — что выбрать?

Ответ. Go — простота, один бинарник, goroutines; Elixir — fault tolerance OTP, hot code upgrade, телеком/web realtime. Подробнее здесь — архитектура BEAM, Go.

Вопрос. Ecto Elixir tutorial — когда учить ORM?

Ответ. После Mix, struct, pattern matching. Ecto — не ActiveRecord: changesets, explicit queries. Phoenix генерирует scaffold. Подробнее здесь — типы, оглавление.

Вопрос. LiveView Phoenix — что это без JavaScript?

Ответ. Server-rendered UI по WebSocket — состояние на сервере, diff на клиент. Нужен Phoenix после базы. Подробнее здесь — оглавление, веб в энциклопедии.

Вопрос. BEAM VM explained — почему миллионы процессов?

Ответ. Процессы BEAM легковесные (~KB), изолированы, общаются сообщениями; scheduler на ядрах CPU. Основа масштаба WhatsApp/Discord-class. Подробнее здесь — архитектура BEAM.

Вопрос. mix new project Elixir — как создать проект?

Ответ. mix new my_app, cd my_app, mix test. Для umbrella — mix new my_app --umbrella. Подробнее здесь — первая программа.

Вопрос. Elixir string vs charlist ~c — в чём разница?

Ответ. Double-quoted — UTF-8 binary; ~c'' — charlist для legacy Erlang API. Используйте strings по умолчанию. Подробнее здесь — типы.

Вопрос. with statement Elixir example error handling?

Ответ. with {:ok, a} <- step1(), {:ok, b} <- step2(a) do ... else ... end — цепочка без вложенных case. Подробнее здесь — управление, приложения.

Вопрос. Elixir concurrency vs threads — как это работает?

Ответ. Не OS thread на процесс: BEAM scheduler multiplexing; процессы не делят память. Сбой одного не роняет всё при supervision. Подробнее здесь — процессы, BEAM.

Вопрос. José Valim Elixir why created — зачем язык?

Ответ. Продуктивный синтаксис + надёжность Erlang/OTP для modern web и distributed systems. Подробнее здесь — история.

Вопрос. ExUnit Elixir test example — как писать тесты?

Ответ. test/my_app_test.exs, use ExUnit.Case, assert, mix test. Async — только при изоляции. Подробнее здесь — приложения.

Вопрос. Nerves Elixir IoT — что это?

Ответ. Elixir на embedded (Raspberry Pi) с OTP; ниша после базы BEAM. Упоминание экосистемы — оглавление, архитектура.

Вопрос. Elixir job salary remote — востребован ли язык?

Ответ. Меньше вакансий, чем Java/Go, но стабильный спрос в fintech, SaaS, realtime. Навыки BEAM ценятся за fault tolerance. Подробнее здесь — приложения, оглавление.

Вопрос. Hello World Elixir iex example?

Ответ. В iex: IO.puts("Hello, World!") или файл .exs + elixir hello.exs. Подробнее здесь — первая программа.

Вопрос. OTP Elixir what is — простыми словами?

Ответ. Open Telecom Platform — набор паттернов BEAM: Supervisor, GenServer, Application — "let it crash" + автоперезапуск. Подробнее здесь — архитектура BEAM, процессы.


Что запомнить

Elixir — функциональный язык на BEAM (Erlang VM): легковесные процессы, message passing, OTP (Supervisor, GenServer). Синтаксис — Ruby-подобный, семантика — Erlang/OTP.

Основные особенности:

  • Неизменяемость и pattern matching (=, case, with);
  • Pipe |> — линейные data pipeline;
  • Процессы — изоляция и fault tolerance "let it crash";
  • Mix — сборка, deps, тесты; Hex — пакеты.

Области: веб (Phoenix), realtime, телеком, IoT, распределённые системы.

Три правила:

  1. Явные tuple-контракты {:ok, _} / {:error, _} вместо exceptions для control flow;
  2. Не создавайте атомы из внешних данных;
  3. OTP supervision — для stateful и долгоживущих компонентов.

Куда идти дальше

ТемаРаздел
Phoenix и экосистемаElixir — о разделе
Scala (JVM-сервисы)Scala — о разделе
HTTP и интеграцииHTTP как основа веб-интеграций

См. также

Другие статьи этого же раздела в боковом меню (как на странице "О разделе").