狠狠撸

狠狠撸Share a Scribd company logo
Erlang 入門 括弧が要らない! Windowsでも楽ちん! 並行プログラミングもOK! 英語OKなら何気に資料も多いぞ! ???そんな関数型言語 Erlang にIT土方系PHPerが果敢にも挑戦している最中です。 id:msakamoto-sf 坂本 昌彦 [email_address]
最初に 場所を提供していただきました 株式会社  EC ナビ様 ありがとう御座います! ヽ (? ー `) ノ
Erlangって? Ericsson社(スウェーデン, ストックホルムにある電話通信会社)が開発した言語 1982-1986年くらいまで、いろんな言語(Lisp, Prolog, Parlogなど)を研究して、並行?耐障害性?適度に抽象的な言語を探求したが??? 1987年、結局Erlangという言語を開発。 オープンソースになったのは1998年になってから。 実際はErlangという言語仕様+OTP(Open Telecom Platform)というSDKがセットで、Erlang/OTPと表記されたりもする。
「あーらん」? 数学者のアグナー?アーラン (Agner Krarup Erlang) から名前をとって命名。 ERicsson LANGuage の略? 当時のEricssonの研究所所長によれば、この二重の意味は意図的だった。 http://www.atmarkit.co.jp/news/200704/27/erlang.html
知名度UPのきっかけ。 Twitterがバックエンドで使っているメッセージングサーバが、Erlangで実装されたIMサーバ"ejabberd"を使っていることがWebに出たあたりから? 正直発端はよく分かりません(^_^;)。「アルファギークに逢ってきた」でも「使ってないよ」みたいな言い方してるし???。 http://www.atmarkit.co.jp/news/200704/27/erlang.html http://www.ejabberd.im/
なぜLisp/Schemeじゃないの? 関数型言語をやってみたかったんだけど???。 LISP系って、LispとかSchemeとかに分派してるみたいだし、処理系もなんか色々あるみたい。*nixで動くのが本流みたいで、Windowsでまともに動かせるのってMIT-GNU Scheme位? EmacsのEmacs-Lispであんまり良い思い出がない。 LispとかScheme系って、話題がなんかやたらと数学的っぽい感じの難しい話が多いような気がする。 数学問題解きたいわけじゃなくて、関数型言語でWebとか弄りたいだけなんだが???。
なぜErlang? 「分散」「並列」とかいう単語が格好良さげ。 実装の「本家」がはっきりしていて、しかもちゃんとWindowsバイナリも出してくれてる(←大事。) Web系の処理とかも普通に楽しめそう。 括弧の嵐がない。 なんか、英語のドキュメントであればTutorialやら入門編やらReferenceマニュアルやらが、本家のサイトから容易に辿れてしかも大量にあるんですけど。
PHPerのアナタにこそErlang(w 「PHPerって結局さぁ???」 とか技術的にDISられそうになったらすかさず、 「Erlangも出来るぜ!」 とか話せれば、見る目も変わる!! ???と思ったけど、そもそも「ハァ?Erlang?何それ」と返されるような気もしなくもない。(??ω?`) でも、自分の作ったWebアプリを、Erlang使って大量プロセスからアクセスさせたりってなんか格好よくね?みたいな。
Erlang/OTP http://www.erlang.org/ からDLできるのは、2008/07現在R12B-3というバージョン。 "otp"とかついているが、これがErlang/OTPのこと。 Erlang自体のバージョンは現在 5.6(.3) Erlangは言語としての仕様と実装。OTPはカーネルを含むライブラリと、システムアーキテクチャの実装。 C#と.Netみたいな関係?
Windows用のバイナリ http://www.erlang.org/ からDLできる。 それなりに大きいので、BitTorrentでDLした方が良いかも。 インストーラを実行すると、デフォルトでは以下のディレクトリにセットアップされます。 "C:rogram Filerl5.6.3" PATHは手動で設定する必要有り。 実際は更にその中の"erts-5.6.3in"にPATH設定すべき?(epmdとか色々入ってるし)
Erlangの世界(0) - ようこそ、Erlangの世界へ - "Hello, Erlang!"
"Hello, Erlang!" 以下のファイルを適当なディレクトリに、"hello.erl"として保存。 -module(hello). -export([start/0]). start() -> io:format("Hello, Erlang!~n").
"Hello, Erlang!" コマンドプロンプトを立ち上げ、保存したディレクトリにCDした後、erl(対話型Erlangシェル)を起動し、以下のコマンドを実行。 C:n_vitrorlang>erl Eshell V5.6.3  (abort with ^G) 1> c(hello) . {ok,hello} 2> hello:start(). Hello, Erlang! ok
"-module(hello)." "モジュール名"を指定する。 ファイル名から拡張子を除いた部分と同じ。 贰谤濒补苍驳のソースコードの拡张子は&补尘辫;辩耻辞迟;.别谤濒&补尘辫;辩耻辞迟;。
"-export([start/0])." 外部公開する関数をリスト形式(後述)で指定する。 C言語のexportとほぼ同意。 ここで指定していない関数は、内部でのみ使われ、他のモジュールからは呼べない。 "/0"というのは引数の数。(後述)
start() ->  io:format("Hello, Erlang!~n"). start()関数の実装部分。 io:format ≒ printf() 書式指定はやや特殊。 末尾"."(ピリオド)は関数の終端を表す。
"c(hello)." シェルコマンド。 "hello.erl"をコンパイルして、"hello.beam"ファイルを生成する。 "モジュール名.erl"ファイルの探索はカレントディレクトリを基準の相対パス。 例:' c("dir1/hello2"). ' シェルコマンドは他にも沢山ある。 "h()."でヘルプ表示。 シェルを終了するには "halt()."
"hello:start()." "モジュール名:関数名(引数)." で指定したモジュールの関数を実行。
Erlangの世界(1) 変数と束縛
変数名は大文字で始まる英数字 とアンダースコア("_") Erlangシェルで実験。 C:n_vitrorlang>erl Eshell V5.6.3  (abort with ^G) 1> Var1 = 100. 100 2> Var1_2 = 200. 200 3> var2 = 300. ** exception error: no match of right hand side value 300 4> Var2-1 = 400. * 1: illegal pattern OK! NG!
変数への代入は 一度だけ ! Erlangシェルで実験。 9> Var1 = 100. 100 10> Var1 = "ABCD". ** exception error: no match of right hand side value "ABCD" 11> b(). Var1 = 100 ok
「束縛」? 関数型言語では、変数名に値を設定するのを「束縛」(bind)と呼ぶ言語が多いらしい???。 erlシェルでは、b()で束縛されている変数を表示し、f()で束縛を解除することもできる(!)。 11> b(). Var1 = 100 ok 12> f(). ok 13> Var1 = "ABCD". "ABCD"
Erlangの世界(2) アトム (atom)
C言語での列挙型。定数みたいな。 "名前"のみの存在。RubyならばSymbol。 PHPには該当する概念が無い。強いて言えばdefine()した定数? 小文字から始まる。 大文字から始まる場合や、 "_", "@" を含む場合はシングルクォーテーションで囲める。 17> hello. hello 18> 'Friday Night'. 'Friday Night' 19> 'user_01@example.com'. 'user_01@example.com'
Erlangの世界(3) タプル (tuple)
複数の変数をひとまとめにする単位 C言語の構造体に近いが、メンバに名前がない。 配列的な操作は出来ない。 データの「型」に近い。 タプルの作成例:↓ 1> X = {1, "hello", world }. {1,"hello",world} 2> Y = { {orange, 100}, {apple, 300} }. {{orange,100},{apple,300}}
タプルの値の取得(1) パターンマッチ(重要) 3> {V1, V2} = X. ** exception error: no match of right hand side value {1,"hello",world} 4> {V1, V2, V3} = X. {1,"hello",world} 5> V1. 1 6> V2. "hello" 7> V3. world
タプルの値の取得(2) パターンマッチ(重要)その2 9> V1 = { apple, 100 }. {apple,100} 10> V2 = { orange, 200 }. {orange,200} 11> { apple, Price } = V1. {apple,100} 12> { orange, Price_orange } = V1. ** exception error: no match of right hand side value {apple,100} 13> { orange, Price_orange } = V2. {orange,200} 14> { Price, Price_orange }. {100,200}
Erlangの世界(4) リスト (list)
いわゆる配列 []で囲む。 1> X = [1, "Hello", world, 2 + 3, { apple, 10 }, [ 4, 5, 6 ] ]. [1,"Hello",world,5,{apple,10},[4,5,6]]
いわゆる配列 []で囲む。 1> X = [1, "Hello", world, 2 + 3, { apple, 10 }, [ 4, 5, 6 ] ]. [1,"Hello",world,5,{apple,10},[4,5,6]]
値の取得(HeadとTail) "|"で区切ったlistで受け取る。独特。 「何番目の要素」を使いたければlists:nth(N, List)。 要素番号は 1 始まり!! 2> lists:nth(1, X). 1 3> [H | T] = X. [1,"Hello",world,5,{apple,10},[4,5,6]] 4> H. 1 5> T. ["Hello",world,5,{apple,10},[4,5,6]]
Erlangの世界(5) レコード (record)
連想配列みたいな。 普通は、ヘッダーファイル的なファイル(.hrl)の中で定義して、includeとかする。erlシェル上であればrr()で。 まず下のファイルを records.hrl として保存する。 -record(person, {  %%  デフォルト値有り name = "anonymous",  %%  デフォルト値無し age,  weight  }).
レコードの作成?参照 erl シェルから rr() で読み込んでみる。 1> rr("records.hrl"). [person] 2> V1 = #person{}. #person{name = "anonymous",age = undefined, weight = undefined} 3> V2 = #person{ name = "Jon", age = 20, weight = 60 }. #person{name = "Jon",age = 20,weight = 60} 4> V3 = #person{ name = "Smith", age = 30, weight = 58 }. #person{name = "Smith",age = 30,weight = 58} 5> #person{ name = N, age = A, weight = W } = V3. #person{name = "Smith",age = 30,weight = 58} 6> [ N, A, W ]. ["Smith",30,58]
Erlangの世界(6) 関数 (function)
引数の数の異なる関数は区別される。 引数の数: Arity -module(funtest1). -export([funtest/0, funtest/1, funtest/2]). funtest() -> -1. funtest(N) -> N * 2. funtest(N, M) -> N + M. -> 1> c(funtest1). {ok,funtest1} 2> { funtest1:funtest(), funtest1:funtest(10), funtest1:funtest(20, 30) }. {-1,20,50}
"ガード"による区別 " 節 " という概念で ";" で分ける。 -module(funtest2). -export([fact/1]). fact(N) when N > 0 -> N * fact(N - 1); fact(0) -> 1. -> 1> c(funtest2). {ok,funtest2} 2> funtest2:fact(5). 120
fun() 名前の無い関数で、変数経由で実行できる。 1> Double = fun(X) -> X * 2. * 1: syntax error before: '.' 1> Double = fun(X) -> X * 2 end. #Fun<erl_eval.6.13229925> 2> L = [ 1, 2, 3, 4]. [1,2,3,4] 3> lists:map(Double, L). [2,4,6,8]
今回はここまで。 次回はifやcase、try-catch、プロセスの実行までできたらと思います。 参考URL: http://www.erlang.org/ http://www.trapexit.org/Category:CookBook クックブック、Tutorialなど豊富? http://erlang-users.jp/ http://dsas.blog.klab.org/archives/cat_50029902.html DSASスゴスギ。

More Related Content

Introduction to Erlang/OTP