Erlang はじめました

田中です。お久し振りです。

TECHSCORE Advent Calendar 2015 の 9 日目の記事です。

唐突ですが、Erlang はじめました。

Erlang がどんな言語か、ざっくり言えば、こんな感じです。
・並列処理/分散処理に特化されている
・関数型言語で文法が特殊

この記事では、Erlang の始め方と、言語の雰囲気がわかるような簡単なプログラムについて書きます。少しでも Erlang に興味を持って頂ければ幸いです。

ところで、"Erlang"  は「アーラング」より「アーラン」が良いでしょう。"ng"  は「有声軟口蓋鼻音」です。日本語の「ん」は、後に続く音によって変化し、例えば「まんが」「さんぽ」「おんど」の「ん」は全て違う音です。この内、「まんが」の場合のように、カ行/ガ行音の前の「ん」が有声軟口蓋鼻音です。ですから「アーラング」と言うつもりで最後の「グ」を我慢するのが良いと思います。

インストール

各環境の Erlang はここから取得できます。
https://www.erlang-solutions.com/resources/download.html

筆者は CentOS 7 を使っていますが、問題なくインストールできました。

Erlang シェルで実行

コマンド erl で Erlang シェルが起動します。対話式に Erlang が実行できるので、とりあえず、触ってみましょう。

ファイルに書いた関数をシェルで実行

Erlang シェルでは関数の定義はできません。ファイルに関数を定義し、Erlang シェルから呼び出してみましょう。

お約束の "hello, world" です。

● mytest.erl

このファイルを Erlang シェルでコンパイルして実行します。

シェルを使わず直接コンパイルして実行

上記の方法は開発時には便利ですが、シェルなしで実行できなければ話になりませんよね。
次は、コマンドラインから直接コンパイルして実行してみましょう。

引数に名前を指定して、"Hello, ○○○!" と表示させます。

● mytest2.erl

コンパイルのコマンドは erlc です。

スクリプトとして実行

練習のため、ちょっとしたプログラムを Erlang で書いてみたいのに、いちいち上記のようにしなければならないのは面倒ですよね。
escript を使えば、コンパイルせず、直接実行することができます。

● hello.erl

実行権限を付与して実行します(勿論、escript hello.erl としても良いです)。

これなら、気軽に Erlang を使ってみよう、という気になりませんか?

再帰呼び出しで反復処理

Erlang はいわゆる関数型の言語です。for ループとかはありません。反復処理は再帰呼び出しで行います。

リストの先頭要素を head、残りの部分を tail と呼びます。Erlang は、リストの再帰処理が書き易いよう、head と tail の分解及び結合が簡単にできるように設計されています。

では、これを使って、リストの要素を新しい要素で置き換える関数

replace(新要素, 旧要素, リスト)

を書いてみます。

● f_test.erl

(注:この replace は、あくまでも練習のための例です。本気で使ったら stack overflow になるかもしれません。"末尾再帰最適化" で検索!)

実行してみましょう。

上記 ② においては、引数を受け取る段階で、リストを head と tail に分解し、head が旧要素と一致するかどうかの検査までを行っているわけです。
このような仕組みのおかげで、慣れればループなんかなくても気にならなくなります(きっと)。関数型プログラミングの勉強のために Erlang を選択するというのも悪くないかもしれません。

とはいえ、Erlang と言えば、やはりアクターモデルによる並列処理でしょう。

アクターモデル

複数のスレッドを起動して並列に処理を行うと競合が発生します。どうしますか?

1 つの解決策は、ロックを取得し、ロックを取得したスレッド以外には待機させる、という方法です。Java の synchronized 文とかですね。

また、「競合が発生するのはスレッドが処理の途中で勝手に割り込むからだ。だから割り込むのやめよう」というのが別の方法で、これがファイバとかコルーチンとか呼ばれてるやつです。

これらに対し、「いや、そもそもメモリを共有しなければ競合なんてありえないでしょう」というのが Erlang の考え方です。アクターと呼ばれる Erlang の軽量プロセスは、プロセス間でメモリを共有せず、互いにメッセージ(数値でもリストでも何でも良い)を送りあって並列処理を行います。これがアクターモデルと呼ばれています。

メッセージの送信は、演算子 !(感嘆符) を使って、

プロセスID ! メッセージ

で行います

まず ! の動作確認のため、Erlang シェルのプロセスにメッセージを送ってみます。

では、以下の仕様の box プロセスを作成し、このプロセスと Erlang シェルのプロセスの間で通信してみましょう。

[box プロセスの仕様]
・リストを保持する。
・メッセージ {送信元プロセスID, {put, アイテム}} を受け取ると、リストにアイテムを追加し、追加した旨の文字列を送信元プロセスに送る
・メッセージ {送信元プロセスID, show_list} を受け取ると、現在のリストを送信元プロセスに送る

メッセージの受信は receive で行います。

● am_test.erl

プロセスの起動は関数 spawn で行います。

簡単な例ですが、ちゃんとプロセス間でメッセージの送受信ができましたね。

Erlang をはじめてみた感想

Erlang の独特の文法は、趣味で勉強する分にはとても面白いのですが、これで業務アプリケーションを書くとなると、やはり、まだちょっと抵抗があります。それでも、アクターモデルによる並列処理は、頑張って習得する価値があると感じました。

私たちの Erlang はこれからだ!

(筆者の次回作に御期待下さい。)

参考文献

Hébert,Fred (2014)『すごいErlangゆかいに学ぼう!』(山口能迪訳) オーム社.

この本は、もともと Web で公開されていた記事が書籍化されたもので、Web 版は今でも無料で閲覧できます。
原文:http://learnyousomeerlang.com/content
翻訳:http://www.ymotongpoo.com/works/lyse-ja/index.html

Comments are closed, but you can leave a trackback: Trackback URL.

Advent Calendar 2015の連載記事

  1. TECHSCORE Advent Calendar 2015
  2. Redshift と PostgreSQL に同時に JDBC 接続する
  3. Lombok で Spice up your Java!
  4. 画像を指定するだけ!非デザイナーでも簡単にそれっぽい配色ができるツールを作ってみた
  5. 新卒文系エンジニアの記録:配属半年間の失敗を振り返ってみた
  6. 非同期処理のすすめ
  7. ioDrive2の導入で支える、そのIOPS - 導入検討編.
  8. GoでパイプラインからSlackに通知する
  9. fuse でオレオレファイルシステムを作ってみた (Haskell で)
  10. Erlang はじめました
  11. ちょっと地味なビルドとリリースの話 (レガシーシステム改革、はじめの一歩)
  12. Java8 最速 boolean[] to Stream 選手権
  13. Google Apps の Directory API にてWebブラウザを介さずに認証する
  14. 風データをビジュアルに表現する
  15. マイクロフレームワーク「Ninja」を使ってみる
  16. 赤ちゃんvimmerからよちよちvimmerにクラスチェンジを果たすためのTips
  17. PostgreSQL FDW を作ってSQLでログ検索してみた
  18. Goで偽名ジェネレータを作りました
  19. 書き込み中に削除されたファイルを救出する
  20. 運用情報更新のススメ
  21. ちゃんと読んでくれましたか?
  22. Presto コネクターを実装する 第三回
  23. Ruby2.3を触ってみる
  24. Git 困ったときのtips集
  25. 5分で読む入門編:Java 8 ラムダ式 コレクション編(2)リストの検索
  26. CloudFront (+ S3) + JWPLAYER で様々なデバイスのブラウザから動画をストリーミング再生する