2008-01-29 関数型言語って何がすごいんですか

C使いの人に、
関数型言語って何がすごいんですか
と聞かれて、
じゃあC言語で accumulator すなわち、数nをとり、「数iを取ってnをiだけ増加させ、その増加した値を返す関数」を返すような関数を書いてみろよ
って言ったら、
値を返す関数を返すような関数・・・? オンドゥルルラギッタンディスカー
で、会話が続かない。
さらに、C使いのターン。
関数に関数を渡せる? Cだって関数ポインタ渡せますよ。
チューリング完全なんだから、どんなプログラムだって書けますよ。
と仕掛けてきた。そこで、
じゃあ、3回呼ぶと動作が変わる関数を書いてみて。
f();
f();
f();
f();
と呼ぶと、
3
2
1
liftoff
って出力されるやつ。ロケットみたいな。
できました。
#include <stdio.h> void f() { static int count = 3; if (count) { printf("%d\n",count); count--; } else printf("liftoff\n"); } int main(void) { f(); f(); f(); f(); return 0; }
OK. じゃあさ・・・。実はロケットは2機あったんだよ。ロケットg。カウントダウン別々で。
f();
f();
f();
f();
g();
g();
と呼ぶと、
3
2
1
liftoff
3
2
ってなるようにしてくれ。
と問題をだしたら、白旗をあげて、
安西先生・・・関数をコピーしたいです・・・
となった。関数がファーストクラスなのが関数型言語の特徴さ。
おっと、関数型言語に触れてしまったか。甘い痺れがいつまでもとれないだろう?
javascript ならこうなります。
function rocket(n) { return function () { if (n) { console.log(n); n--; } else console.log('liftoff'); } } var f = rocket(3); var g = rocket(3); f(); f(); f(); f(); g(); g();

C++等なら同じことはオブジェクトでできる(例:Boostやデリゲート).
Lisp/Schemeが有名だった昔はこれが大きな特徴だったのだけど,
今はこういうことを関数型言語の特徴というのはあまり良くない気が……
副作用のない純粋な関数型言語ではできないことだし.
現にHaskellはできない,Ocamlは参照型を使う必要あり.
Objects are a poorman’s closures. 逆も然り。
うーん。この日記でやりたかったのは、手続き型言語しか知らない人に、関数をコピーしたいな、つまり、関数がファーストクラスだったらな、という切り口を見せたい、ということなんです。
副作用のない純粋な関数型言語ではできないこと という点は耳が痛いです。
もしその点をも満たしていて、しかも、関数型言語の特徴がよくわかる例があれば、ぜひ教えてください!
このスレッドを自分はまだ読んでいません。
http://groups.google.com/group/fa.haskell/browse_thread/thread/40221a24b1f31422
コメントお待ちしています。