Erlang Super Lite [Chapter 2]
Erlangといえば「Prolog大好き!」「でも後に続く言語ないんだよねー」とあちこちで言いまくっていたら「Erlang ちょっと Prolog っぽいらしいよ」と言われ、飛行機本を買って読んでいたら文法は確かに近いしパターンマッチはユニフィケーション、でもバックトラックがないなんて……と落ち込んでいたら、あれの並列処理って要はヒューイットの Actor じゃねーか? ということに思い至り、あー勉強しなきゃなーと思ってたらこんな素敵なイベント発見。そりゃ行くさ。
なんかついつい語りたくなっちゃってダラダラ下らないことを喋ってしまいました。すみません。>ALL
喋った&記憶に残ったことをメモっておきます。
Chapter 2 までの復習
- [X|Y] を cons 演算子というのは、Prolog も Erlang もパターンマッチングによる逆演算があるので car / cdr / cons が一緒に表現できるため。
- 関係演算子が =< >= なのは Prolog の影響のはず。「矢印にならないように」と覚えてください。
- 変数が大文字始まりも Prolog からだと思う。小文字symbol の場合は "_" をつける。Erlang の場合は _hoge は内部変数っつか「いちおー名前はつけたけど参照しないでね」って意味なのでちょっと違う。
- 再帰のときに一時変数を使いたくて作る arity は Prolog だと名前を変えるべきという慣習があるので Erlang もそれを踏襲しているのかもしれませんね。SICP でも xxx_iter って奴がしょっちゅう出てくるけどあれみたいなものか。
Chapter 3
case とか if について
- case はパターンを書き、if は Guard を書くのが違い。
- 飛行機本でピンとこなかった Guard の意味がやっと分かった気がする。
factorial(0) :- 1. factorial(N) :- N * factorial(N - 1).
-
- Erlang だと Guard を使うことによってこう書ける。
factorial(N) when N > 0 -> N * factorial(N -1). factorial(0) -> 1.
ちょっと脱線:tuple について
例外
- 例外処理は普通だけど throw でどんなものでも投げられること、catch はパターンマッチで捕まえるところがミソではある (笑)
第9章
なんでいきなり飛ぶのかというとまずは sequential programming を一気に片付けようというお話。
高階関数・関数型言語とはなんぞや、など
- fun()*4 の end ってちょっとキモいよね、という話。
Z = fun(X) -> 2 + X end.
- なんか Erlang って書いてると関数型言語って気がしないんだけど。
- 関数型言語ってそもそもなに?
- 無名関数があるから関数型? じゃあ ruby は proc とかあるから関数型?
- map があれば関数型? でもあんなのどの言語でもすぐ書けるよね? 組込みかどうかは意味論的には意味ないし。
- 本質は「関数の戻り値を引数に渡して、その戻り値をまた引数に渡して」といって計算が完結する計算モデルなんじゃないの?
- この場合の「関数」は数学的関数なので、同じものを入れたら同じ結果が出てこないといけない。
- だから再代入があったら pure じゃない。というのがオイラ (naruoga) の理解。
- つことで Erlang は「一個の関数の表現として複数の arity がある
値を返さない arity がある*5」という意味では関数型っぽくはないけど、破壊代入を許さない、結果を次々と渡していくという計算モデルだとすれば関数型。 - そもそも「関数型プログラミング」という概念は 1977 年、Backus の FP で提唱されたものなので、「Lisp は関数型言語」は後付けに過ぎず、Lisp が持っている機能があるかどうかで関数型言語かどうかを考えるのはナンセンス。
包含リスト
- こういう構文ですね (Wikipedia:erlang の quicksort の例より)。*6
[X || X <- Rest, X < Rest]
- この構文は許せるか? Xが先に来るのってキモくない?
- 数学だと「すべての x において、...が成り立つ要素の集合」とか普通なので違和感がない
- でも matz さんはあんまりこの構文が好きじゃないらしい
- ので ruby には入らないとか。
Binaries
- まー言っていれば「バイナリを作るための構造体 with 便利な関数」
- ミソはここも包含バイナリが書けて、なおかつパターンマッチができること。
- 通信のためのヘッダつくったりに便利。
そして演習
- ぜんぜん演習やらなかったので各自自習しましょう (^^;)
- 演習 3-10 は文書の折り返しの話。filled と言えばある幅に合わせて折り返す。後ろは揃わない。justify と言えば両端揃え。英文では基本ですよ (^^)。
*1:むろん Prologer としては if とか case とか使ったら負けである。
*2:関係ないけど Python の tuple は immutable で List は mutable という明確な違いがあるそうです。
*3:これは後ほど Masahito さんに Twitter でフォローいただきました。感謝!
*5:Prolog 脳なので間違えた。Erlang は最後に評価した結果を常に返すので、値を返さない式は存在しない。ただ Prolog 風に arity を複数書いてパターンマッチでどっちかを使うというコードを書いていくこともできるということを意味してます。
*6:矢印の向きが思いっきり反対になってたので修正。おはずかしや。