No Programming, No Life

プログラミング関連の話題や雑記

Erlang基礎文法ひとめぐり

はじめに

ErlangかわいいよErlang

ピリオド

ピリオドは式の終わりを表す。

.

コメント

コメント
%から行末までがコメントになる。ブロックコメントはない。

% コメント
%% コメント

NOTE: 慣例として%%がよく使われる。

簡単な演算

1> 2 + 3 * 4.
14
2> (2 + 3) + 4.
9
3> 16#cafe * 32#sugar. %% 16進数と32進数
1577682511434

変数

1> X = 12345678.
12345678
2> X.
12345678
3> X * X * X * X.
23230565505791726714743139856

NOTE: 変数は必ず大文字で始めなければならない。

Erlangの変数は単一代入変数。再代入はできない。既に値を設定した変数の値を変更しようとするとエラーになる。既に値が代入されている変数は束縛済み変数(bound variable)と呼ばれる。そうでない変数は未束縛変数(unbound variable)と呼ばれる。

4> X = 1234.
** exception error: no match of right hand side value 1234
5> X.
12345678

パターン照合

ほとんどの言語では = は代入文を意味するがErlangでは = はパターン照合処理を意味する。Lhs = Rhs の意味は「右辺(Rhs)を評価して、その結果と左辺(Lhs)のパターンを照合する」こと。

1> X = 2 + 4.
6
2> Y = 10.
10
3> X = Y.
** exception error: no match of right hand side value 10
4> X = Y - 4.
6

Erlangの変数とは値への参照(値を格納している記憶領域を指すポインタ)でしかなく、この値を変更することはできない。単一代入は代数のようなもの。Erlangで X = X + 1 はまだ使われていない変数名を使って X1 = X + 1 のように書けばよい。

浮動小数点値

1> 5/3. %% / は常に浮動小数点値を返す
1.6666666666666667
2> 4/2. %% / は常に浮動小数点値を返す
2.0
3> 5 div 3. %% 整数の除算
1
4> 5 rem 3. %% 整数の剰余
2
5> 4 div 2.
2
6> Pi = 3.14159.
3.14159
7> R = 5.
5
8> Pi * R * R.
78.53975

アトム

Erlangでは数値以外の不変値を表すのにアトム使う。Rubyのシンボルみたいなもの。
アトムは小文字で始まり、その後に英数字、アンダースコア(_)、アットマーク(@)の列が続く。

%% アトムの例その1
red, december, cat, meters, yards. joe@somehost, a_long_name

アトムは単一引用符(')で囲んで示すこともできる。これを使うと大文字で始まるアトムや英数字以外の文字を含むアトムを作れる。

%% アトムの例その2
'Monday', 'Tuesday', '+', '*'m 'an atom with spaces'

アトムの値はアトムそのものなので、アトムだけのコマンドを入力するとErlangシェルはそのアトムの値を表示する。

1> a.
a
2> 'a'. %% 'で囲んでいるが、結果は'なしで表現できるため、'なしになる
a
3> 'Atom'.
'Atom'

タプル

ある個数の項目を一つにまとめたいときはタプルを使う。タプルを作るには、表現したい値をカンマで区切り、中括弧で囲む。例えば人の名前と慎重を表現したいときは

{joe, 1.82}

のように書く。このタプルはアトムと浮動小数点値で構成されている。
例えば点(Point)を表すには次のようにする。

P = {10, 45}

タプルが何に使われているかを思い出しやすくするために、タプルが表現するものを示すアトムを最初の要素に入れておくことが多い。

P = {point, 10, 45}

タプルを作る

1> F = {first_name, fumo}.
{first_name,fumo}
2> L = {last_name, kmm}.
{last_name,kmm}
3> P = {person, F, L}.
{person,{first_name,fumo},{last_name,kmm}}

タプルから値を取り出す

タプルから値を取り出すにはパターン照合演算子(=)を使う。

1> Point = {point, 10, 45}.
{point,10,45}
2> {point, X, Y} = Point.
{point,10,45}
3> X.
10
4> Y.
45

タプルから値を取り出すには、タプルと同じ形(構造)で、タプルの取り出したい値に対応する箇所に未束縛変数を置いたパターンを書けばよい。

1> Person = {person,
1>            {name, joe},
1>            {height, 1.82},
1>            {footsize, 42},
1>            {eyecolor, brown} }.
{person,{name,joe},
        {height,1.82},
        {footsize,42},
        {eyecolor,brown}}
2> {_, {_, Who}, _, _, _} = Person.
{person,{name,joe},
        {height,1.82},
        {footsize,42},
        {eyecolor,brown}}
3> Who.
joe

興味のない変数の代わりとして無名変数の「_」を使っている。シンボル_は通常の変数と異なり、1つのパターンの中で何度か使う場合でも同じあたいに束縛されなくてもよい。

リスト

個数が決まっていないものを格納するときにはリストを使う。リストを作るには各要素をカンマで区切って、角括弧で囲む。

1> ThingsToBuy = [{apples, 10}, {pears, 6}, {milk, 3}].
[{apples,10},{pears,6},{milk,3}]
%% 要素はどんな型でも構わない
2> [1+7, hello, 2-2, {cost, apple, 30-20}, 3].
[8,hello,0,{cost,apple,10},3]

要素のないリストは空リスト([ ])と呼ぶ。
リストの先頭要素をヘッドという。リストからヘッドを取り除いたときに残るものをテールという。例えばリスト [1, 2, 3, 4, 5] のヘッドは整数の1で、テールは [2, 3, 4, 5] というリストになる。
Tがリストならば、[H|T]もまたリストで、ヘッドがH、テールがTになる。縦棒(|)はリストのヘッドとテールの区切りになっている。
リスト構築子 [...|T] を使ってリストを作るときは、Tが必ずリストであるように気を付けなければならない。Tがリストなら「正しい形式」とよばれ、Tがリストでなければ「不正な形式」と呼ばれる。ライブラリ関数のほとんどがリストが正しい形式であることを期待している。
これを使って、リストの先頭に複数要素を追加するには、[E1, E2, ..., En|T] のように書く。

3> ThingsToBuy1 = [{orange, 4}, {newspaper, 1}|ThingsToBuy].
[{orange,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]

リストから要素を取り出す

この場合もパターン照合操作を使う。

4> [Buy1|ThingsToBuy2] = ThingsToBuy1.
[{orange,4},{newspaper,1},{apples,10},{pears,6},{milk,3}]
5> Buy1.
{orange,4}
6> ThingsToBuy2.
[{newspaper,1},{apples,10},{pears,6},{milk,3}]
7> [Buy2, Buy3|ThingsToBuy3] = ThingsToBuy2.
[{newspaper,1},{apples,10},{pears,6},{milk,3}]
8> Buy2.
{newspaper,1}
9> Buy3.
{apples,10}
10> ThingsToBuy3.
[{pears,6},{milk,3}]

文字列

厳密に言えばErlangには文字列は存在しない。文字列は実際には単なる整数のリストである。文字列は二重引用符(")で囲む。

NOTE: 言語によっては文字列として単一引用符(')と二重引用符(")のどちらも使うことができるが、Erlangでは二重引用符(")を使わなければならない。

1> Name = "Hello".
"Hello"

"Hello"は文字列の整数リストの簡易表記である。リストの整数がすべて整数で表示可能であればシェルはリストを文字列として表示する。

2> [1, 2, 3].
[1,2,3]
6> [72, 101, 108, 108, 111].
"Hello"

ドル記号表記($)を使うと文字に対応する整数を調べられる。

4> [$H, $e, $l, $l, $o].
"Hello"

モジュール

モジュールはErlangのコードの基本単位で、どの関数も必ずモジュールに属している。モジュールは拡張子が.erlのファイルに入れておく。コード実行には事前にコンパイルが必要で、コンパイルすると.beam*1になる。

(絶賛書き途中)
随時学習しながら追加してゆきます。

参考書籍

プログラミングErlang

プログラミングErlang

*1:Beam は Bogdan's Erlang Abstract Machine の略。