おがさわらなるひこのオープンソースとかプログラミングとか印刷技術とか

おがさわらなるひこ @naru0ga が技術系で興味を持ったりなんだりしたことをたまーに書くブログです。最近はてなダイアリー放置しすぎて記事書くたびにはてな記法忘れるのではてなブログに移行しました。

クリエイティブ・コモンズ・ライセンス
特に断りがない場合は、本ブログの筆者によるコンテンツは クリエイティブ・コモンズ 表示 - 継承 4.0 国際 ライセンスの下に提供されています。

関数型言語と Erlang についてあれこれ

d:id:naruoga:20091208:1260290590 自分のコメントを読み返してみると嫌に喧嘩腰ですね。せっかくコメントいただいたのに申し訳ないです。>みなさん

最初コメントとして書いてたのですが、長くなって来たのでエントリにします。大したこと書いてないのでスルー推奨。

なお前のエントリでも書いたとおり私は Erlang を「Prolog っぽい言語」という入り口で入ったので、Prolog と比較してどうこう、という考えになるのはご容赦いただくということで。


えっとですね、私として関心があるのは、

そもそも関数型言語 (Functional-Level Language) とはなにか。

根源的な議論になるけれど、そもそも関数型言語とはなにか、一言で答えが欲しい。
私としては Functional Level Programming という言葉を大衆化させた Backus の FP なんかを見ると「数学的関数(すなわち常に同じ値を渡したら同じ結果が戻ってくるもの)の解を別の関数の引数に渡して、……とやって答えが帰ってくるもの」というのが非常に根本的な理解なので、だから破壊代入とか許せないんだけど……。

Wikipediaを見るとやたら長々と書いてあるし*1、いろんな言語の本の序文でそれっぽいことが書いてあるが、微妙に定義が揺れている気がする。

ぜひここが明解にすっと答えが得られるとうれしいのだけど。

関数型言語とパターンマッチと Prolog のユニフィケーション

Prolog は一階述語論理を表現したプログラミング言語なので単なるユニフィケーション (単一化、~= パターンマッチング) だけでなくバックトラックによって「最後まで解が求められないといけない」という縛りがある。だから Erlang (Haskell も?) のパターンマッチングにはバックトラックしなくてもまあしゃーないかという感じ。

でもパターンマッチは右辺と左辺に向きというか方向はないので、あきらかに方向がありそうな -> って記号使うのはイマイチということに関しては関数型だろうが論理型だろうが関係ないと思うのだがどうだろう?

「->」は→じゃなくてλ簡約じゃないの? というコメント(解釈違ってたらごめんなさい)もいただきましたが、λ簡約も向きが明確にある演算だとワタクシ思うのですが。

んで、「Erlang は関数型」ってそんなに大事にしなきゃいけない?

たとえばこの階乗の例。

factorial(N) when N > 0 -> N * factorial(N - 1).
factorial(0) -> 1.

これは確かに factorial(N) の結果が値として帰ってくるんだけど (変数束縛しか使わないと書いたのは間違い、あとで訂正します)、factorial/1 の定義が二つあるのが関数型っぽくないといえば関数型っぽくない。数学の関数の定義なら if / otherwise とか使うところだから。
でも Erlang は破壊代入できない、だから副作用が起きないから関数は常に同じ値を返す、という意味では僕的な関数型の定義には非常にマッチしている。見た目は実に Prolog っぽいが *2

まーそんなわけで、「Erlang は関数型!」ってそんなに強く主張しなきゃいけないの?
言語のパラダイムってそんなに大事にしなきゃいけないの?
それよりも言語設計者がその言語でなにを表現したかったかの方が大事なんじゃないの?
結果として「Erlang ってどうも関数型という感じがしない」という人がいてもいいなじゃないの?

という気がする。


雑文失礼。
それでは。

*1:しかしこの記述、「今ちょっと流行ってる関数型言語ってなんだろう?」と思って見にきた人をいきなり拒絶する内容だよな ^^;

*2:Prolog の述語は値を返さないのでもう一個答えをもらうための変数が必要になりますね。