連載
» 2016年08月30日 05時00分 UPDATE

Dev Basics/Keyword:Erlang(関数型プログラミング言語)

Erlangは、並行処理/分散処理/耐障害性といった特徴を備えた関数型プログラミング言語およびその実行環境だ。

[かわさきしんじ,Insider.NET編集部]
「Dev Basics/Keyword」のインデックス

連載目次

Erlangとは

 Erlangは、並行処理/分散処理/耐障害性といった特徴を備えた関数型プログラミング言語およびその実行環境のこと。もともとはエリクソンのCSLab(Computer Science Laboratory)で開発されたが、現在はオープンソースソフトウェアとして公開されている。ElixirがErlangで実装されていることでも最近は有名だ。

Erlang公式サイト Erlang公式サイト

Erlangの特徴

 Erlangの特徴としては以下が挙げられる。

  • 軽量かつ他から分離されたプロセス
  • 独自のVM上で動作する
  • プロセス間のメッセージパッシング機構
  • 並行/分散プログラミング

 OSネイティブなプロセスよりもはるかに軽量な「プロセス」を持ち、独自の実行環境(Erlang VM)上で動作する。また、Erlangのプロセスは他のプロセスからは分離されていて、メモリ領域を他のプロセスと共有することがなく、プロセス間でのデータ共有はメッセージパッシング機構を使用して行う。このため、Erlangではあるプロセスに問題が発生しても、他のプロセスに影響が及ぶことが少ない。こうした特徴から、Erlangではスケーラブルでリアルタイム性を持った、可用性の高いプログラムを構築できる。

 この他にも、ホットスワップ(システム稼働中に、それを停止させることなく、プログラムの入れ替えが可能)、マシン透過なプロセスといった特徴もある。

 以下では、Erlangのシェル環境と簡単なスクリプトを見ていく。なお、Erlangのインストールなどの説明については割愛する。

Erlangシェル

 Erlangシェルでは対話的にコマンドを入力したり、作成したスクリプトをコンパイルしたりできる。

Windows用のErlangシェル(GUI) Windows用のErlangシェル(GUI)

 まずはシェルを使ってErlangの言語としての特徴を見てみよう。シェルにはコマンドやErlangの式を入力できる。

1> variable = 10.
** exception error: no match of right hand side value 10
2> Variable = 10.
10
3> Variable.
10
4> Variable = 20.
** exception error: no match of right hand side value 20


変数は大文字で始まり、変数への値の束縛は一度だけ

 上の実行例を見ると分かるが、Erlangでは変数の名前は英大文字で始める(1行目でエラーが発生しているように英小文字で始めることはできない)。上のコードで行っているのは代入ではなく、パターンマッチであり、等号の左右の項がマッチするように変数Variableには10が束縛されている。変数への値の束縛(代入)は一度しか行えない(Erlangシェルではf()コマンドで束縛を解除できる)。

 なお、Erlangでは任意の型のデータのことを「ターム」(term、項)と呼ぶ。式や関数の「項」だと考えればよい。シェルに入力する式、コマンドはピリオドで終了する点にも注意したい。

関数

 次に無名関数を作成してみる。無名関数の宣言にはfunキーワードを使用する。

5> Adder = fun(X) ->  
5>   fun(Y) -> X + Y end
5> end.
#Fun<erl_eval.6.52032458>
6> Add2 = Adder(2).
#Fun<erl_eval.6.52032458>
7> Add2(5).
7


無名関数

 Erlangでは関数はファーストクラスオブジェクトであり、上のように関数を返す関数も簡単に記述できる。名前を持った関数は以下に示すように、.erlファイルにモジュールを作成して、その中に記述していく。

-module(foo).
-export([getCount/2]).

getCount([], Count) ->
  Count;
getCount([H|T], Count) ->
  getCount(T, Count + 1).


モジュールと関数(foo.erlファイル)

 ここではリストの要素数を取得する関数を定義している。最初の2行でモジュール(foo)とそのモジュールが外部に公開する関数(getCount/2)を記述している。「getCount/2」の「/2」は関数の引数の個数を表すもので、「アリティ」と呼ばれる。

 最後の4行がgetCount関数の定義となる。上の例のように、Erlangでは1つの関数に対して、複数の関数ボディーを定義可能だ。ボディーはセミコロン(;)で区切り、最後にはピリオド(.)を記述する(同じ名前で引数の数が異なる関数も定義可能)。

 この関数を例えば「getCount([1, 2, 3], 0)」のように呼び出すと、実引数とパラメーターの「パターンマッチ」が行われ、最初にマッチした関数ボディーが実行される。この場合は、getCount関数に空のリスト([])と数値が渡されると最初の関数ボディーが実行され、空でないリストが渡されると2つ目の関数ボディーが実行される。このとき、パラメーターCountにはもう1つの実引数の値が束縛される。

 2つ目の関数ボディーには「[H|T]」という記述がある。Erlangでは、リストを「[先頭要素|それ以降の要素]」のように記述できる(「H」は「Head」を、「T」は「Tail」を意味する)。この場合、パラメーターTにはリストの第2要素以降が束縛される(この時点で元のリストから要素が1つ減っている)。そして、要素が1つ減ったリストと1だけ加算されたCountを指定して、自身を再帰的に呼び出している。このようにすることで最終的には1つ目の関数ボディーが実行され、リストの要素数が得られる。

 このようなリスト操作はErlangプログラミングにおける基本となる。これを実行するにはErlangシェルでソースファイルをコンパイルする。以下に例を示す。関数呼び出し時にリストの要素数の初期値として0を渡していることにも注意しよう。

8> c('foo').
foo.erl:6: Warning: variable 'H' is unused
{ok,foo}
9> foo:getCount([1, 2, 3, 4, 5], 0).
5
10> foo:getCount(["foo", "bar", "baz"], 0).
3


fooモジュールのコンパイルとgetCount関数の呼び出し

プロセス

 最後に、Erlangでのプロセスの扱いを簡単に紹介する。

-module(sample).
-export([fact/1, factproc/0]).

fact(0) -> 1;
fact(N) -> N * fact(N-1).

factproc() ->
  receive
    N when N < 0 ->
      io:format("can't compute~n"),
      factproc();
    N ->
      io:format("factorial of ~p is ~p~n", [N, fact(N)]),
      factproc()
  end.


階乗を計算するプロセス(factproc)

 詳細は割愛するが、fact関数は階乗の計算を実際に行う関数だ。factproc関数はプロセスとして実行され、メッセージとして階乗を求める数を受け取るようになっている(receive式)。receive式にも複数のボディーがある。最初のボディーにはガード節が記述されていて、負数が渡された場合には計算をしないようにしている。また、各ボディーでは最後に「factproc()」として自身を呼び出すことで、プロセスが終了しないようにしている。

 これをコンパイル/実行した様子を以下に示す。

11> c('sample').
{ok,sample}
12> Pid = spawn(sample, factproc, []).
<0.79.0>
13> Pid ! 6.
factorial of 6 is 720
6
14> Pid ! -1.
can't compute
-1


プロセスへのメッセージ送信

 上を見ると分かるように、プロセスを新規に開始するにはspawn関数を利用する。また、作成したプロセスにメッセージを送信するには「プロセス ! メッセージ内容」とする。


 Erlangは、並行処理/分散処理/耐障害性といった特徴を備えた関数型プログラミング言語およびその実行環境だ。本稿では関数やリストの扱い、プロセスの作成とメッセージ送信といったその基本となる要素を簡単に紹介した。

参考資料


「Dev Basics/Keyword」のインデックス

Dev Basics/Keyword

Copyright© 1999-2017 Digital Advantage Corp. All Rights Reserved.

@IT Special

- PR -

TechTargetジャパン

この記事に関連するホワイトペーパー

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。