Gemmaの日記 このページをアンテナに追加 RSSフィード

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();

通りすがり通りすがり 2008/02/11 05:26 これは関数型言語というより,クロージャのオブジェクト指向的使い方.
C++等なら同じことはオブジェクトでできる(例:Boostやデリゲート).

Lisp/Schemeが有名だった昔はこれが大きな特徴だったのだけど,
今はこういうことを関数型言語の特徴というのはあまり良くない気が……
副作用のない純粋な関数型言語ではできないことだし.
現にHaskellはできない,Ocamlは参照型を使う必要あり.

GemmaGemma 2008/02/12 07:47 鋭いですね!その通りです。自分の勉強が足りませんでした。
Objects are a poorman’s closures. 逆も然り。
うーん。この日記でやりたかったのは、手続き型言語しか知らない人に、関数をコピーしたいな、つまり、関数がファーストクラスだったらな、という切り口を見せたい、ということなんです。
副作用のない純粋な関数型言語ではできないこと という点は耳が痛いです。
もしその点をも満たしていて、しかも、関数型言語の特徴がよくわかる例があれば、ぜひ教えてください!
このスレッドを自分はまだ読んでいません。
http://groups.google.com/group/fa.haskell/browse_thread/thread/40221a24b1f31422

コメントお待ちしています。

関数言語勉強中関数言語勉強中 2012/01/30 22:11 お題の件。C言語書きならば、迷わずロケット状態の構造でメモリ確保してポインタを関数に渡すと答えると思いますよ。