Elixir Sample

Elixirは拡張性と保守性の高いアプリケーションを構築するためにデザインされた、動的で関数型のプログラミング言語です。

Elixirは、低レイテンシで分散型のフォールトトレラントシステムや、Webや組み込みシステムの領域で成功を収めている、Erlang VMを利用します。

詳しくは getting started guidelearning page for other resourcesをご覧ください。以下ではElixirのプラットフォームや言語、ツールの概要を説明します。

プラットフォームの特徴

スケーラビリティ(拡張性)

全てのElixirのコードは、隔離された軽量の実行スレッド(プロセスと呼ばれる)の中で動作し、メッセージを通して情報をやり取りします。

current_process = self()

# Spawn an Elixir process (not an operating system one!)
spawn_link(fn ->
  send current_process, {:msg, "hello world"}
end)

# Block until the message is received
receive do
  {:msg, contents} -> IO.puts contents
end

その軽量性により、同一のマシン内で数千のプロセスが 同時に 起動することも珍しくありません。プロセスの隔離により、各プロセスが個別にガベージコレクションされることを許容し、システムの広範に及ぶポーズを減らし、全てのマシンリソースを可能な限り効率的に使うことが出来ます。(垂直拡張)

プロセスは、同一のネットワーク内に存在する、他のマシン上で動作しているプロセスとも通信することが出来ます。これは分散型システムの基盤となり、複数のノードにまたがったシステムの構築を可能にします。(水平拡張)

フォールトトレランス

本番環境で動作するソフトウェアに対する避けられない真実は いつかは壊れる ということです。ネットワークやファイルシステム、サードパーティのリソースを考慮するとその確度はさらに高まります。

障害に対処するために、Elixirはスーパーバイザを提供します。スーパーバイザは何かが失敗した時にシステムの構成要素をどのようにリスタートするかや、動作が保証された既知の初期状態に戻す方法を表します。

children = [
  TCP.Pool,
  {TCP.Acceptor, port: 4040}
]

Supervisor.start_link(children, strategy: :one_for_one)

言語の特徴

関数型プログラミング

関数型プログラミングは、保守性が高く、高速に動作し、また少ない記述量でコードを書く、というコーディングスタイルを促進します。例えば、パターンマッチングはデータを容易に分解し、その内容にアクセスすることができます。

%User{name: name, age: age} = User.get("John Doe")
name #=> "John Doe"

ガードとパターンマッチングをの組み合わせは、あるコードを実行するための特定の条件を、エレガントに match, assert することを可能にします。

def drive(%User{age: age}) when age >= 16 do
  # Code that drives a car
end

drive(User.get("John Doe"))
#=> Fails if the user is under 16

予期される様々な制約の下で、ソフトウェアが動作することを確実にするために、Elixirはこれらの特徴に強く依存します。そしてもし動作しなかったとしても心配無用です。その場合はスーパーバイザがサポートします。

拡張性とDSL

Elixirは拡張可能なようにデザインされています。開発者は生産性を高めるために、特定のドメイン用に言語を自然に拡張することができます。

例として、 ExUnitと呼ばれるElixirのテストフレームワーク を使った簡単なテストケースを書いてみましょう。

defmodule MathTest do
  use ExUnit.Case, async: true

  test "can add two numbers" do
    assert 1 + 1 == 2
  end
end

async: true オプションは、可能な限り多くのCPUコアを使うことで、各 test を並列に実行することを可能にします。assert はコードを内観でき、テスト失敗時に素晴らしいレポートを提供してくれます。これらの機能はElixirのマクロを利用して実現されており、あたかもそれが言語の一部であるかのように、新しい構文を追加することが可能です。

ツールの特徴

成長するエコシステム

Elixirは開発を容易にするための素晴らしいツールを提供します。 ビルドツールであるMix は、プロジェクトの作成、タスクの管理、テストの実行などを容易にする手段を提供します。

$ mix new my_app
$ cd my_app
$ mix test
.

Finished in 0.04 seconds (0.04s on load, 0.00s on tests)
1 tests, 0 failures

Mixは依存性の管理も行うことができ、 Hex パッケージマネージャ と良く統合されています。Hexは依存性の解決と、パッケージのダウンロード機能を提供します。

対話型の開発

IEx (Elixirの対話型シェル) のようなツールは、言語とプラットフォームの多くの側面を利用して、オートコンプリート、デバッグツール、コードの再読込、よく整形されたドキュメントを提供することができます。

$ iex
Interactive Elixir - press Ctrl+C to exit (type h() ENTER for help)
iex> h String.trim           # 関数のドキュメントを表示する
iex> i "Hello, World"      # 与えられたデータ型についてのドキュメントを表示する
iex> break! String.trim/1    # String.trim/1 関数にブレークポイントを設定する
iex> recompile               # その場で現在のプロジェクトを再コンパイルする

Erlang との互換性

Erlang VM 上で動作するElixirは、HerokuWhatsAppKlarnaといった会社が分散型でフォールトトレラントなアプリケーションを構築するために使っている、Erlangエコシステムへの完全なアクセスを開発者に提供します。Elixirプログラマーは実行時の追加コスト無しにすべてのErlang関数を実行することができます。

iex> :crypto.hash(:md5, "Using crypto from Erlang OTP")
<<192, 223, 75, 115, ...>>

Elixirをもっと知るために、getting started guideをお読みください。オンラインドキュメント も提供していますし、Erlang開発者のための速習講座もあります。