Elixirは2012年にJosé Valimによって開発された関数型プログラミング言語です。Erlang VM(BEAM)上で動作し、Erlangの高い並行性と耐障害性を受け継ぎつつ、モダンで親しみやすい構文を提供します。WhatsApp(Erlang)が少数のエンジニアで数十億のメッセージを処理していることからも、BEAMプラットフォームの実力は証明済みです。
Discord、Pinterest、PepsiCoなど、大規模なサービスでElixirが採用されており、特にリアルタイム通信やIoTプラットフォームでの実績が豊富です。
Elixirの基本的な構文を見てみましょう。パターンマッチングとパイプ演算子が特徴的です。
defmodule UserService do
def process_registration(params) do
params
|> validate_input()
|> create_user()
|> send_welcome_email()
|> format_response()
end
defp validate_input(%{"email" => email, "name" => name})
when is_binary(email) and is_binary(name) do
{:ok, %{email: email, name: name}}
end
defp validate_input(_), do: {:error, :invalid_params}
defp create_user({:ok, attrs}) do
case Repo.insert(%User{} |> User.changeset(attrs)) do
{:ok, user} -> {:ok, user}
{:error, changeset} -> {:error, changeset}
end
end
defp create_user({:error, _} = error), do: error
end
パイプ演算子(|>)により、データの変換処理を直感的に連鎖させることができます。パターンマッチングは関数の引数で分岐を表現でき、条件分岐がシンプルになります。
ElixirのキラーフィーチャーはOTP(Open Telecom Platform)フレームワークです。Supervisorパターンにより、プロセスの障害を自動的に検知・復旧できます。
defmodule MyApp.Application do
use Application
def start(_type, _args) do
children = [
{MyApp.Repo, []},
{MyApp.Cache, []},
{MyApp.TaskQueue, []},
MyAppWeb.Endpoint
]
opts = [strategy: :one_for_one, name: MyApp.Supervisor]
Supervisor.start_link(children, opts)
end
end
strategy: :one_for_oneは、子プロセスが異常終了した場合、そのプロセスだけを再起動する戦略です。他にも:one_for_all(全プロセスを再起動)、:rest_for_one(後続のプロセスを再起動)といった戦略を選択できます。「クラッシュさせてよいです」というErlangの哲学により、防御的プログラミングの負担が大幅に軽減されます。
PhoenixはElixirの代表的なWebフレームワークです。特にPhoenix LiveViewを使うと、JavaScriptを最小限に抑えつつ、リアルタイムなインタラクティブUIを構築できます。WebSocketベースの通信で、サーバーサイドの状態変更が即座にクライアントに反映されます。
defmodule MyAppWeb.DashboardLive do
use MyAppWeb, :live_view
def mount(_params, _session, socket) do
if connected?(socket), do: :timer.send_interval(1000, :tick)
{:ok, assign(socket, metrics: fetch_metrics())}
end
def handle_info(:tick, socket) do
{:noreply, assign(socket, metrics: fetch_metrics())}
end
def render(assigns) do
~H"""
システムメトリクス
CPU: %
Memory: %
"""
end
end
Elixirは学習曲線がやや急ですが、並行処理が本質的に求められるシステムには非常に強力な選択肢です。