言語ゲーム

とあるエンジニアが嘘ばかり書く日記

Twitter: @propella

Gtk シグナルと関数の戻り値

つまらない話ですが続けます。Gtk のシグナルが論理的に何なのかと考えてみました。Gtk のシグナルの特徴は送り手が一人だけど受けてが沢山居るという事です。という事は返り値も無く副作用のみなので、関数型大好きな私には受け入れ難い概念です。また、双方向リンクというのはとにかくバグの温床でもあります。しかし。

逆に考えるんだ。シグナルを関数の返り値を抽象化した物だと考えるんだ。

つまり、model が view1 と view2 にシグナルを送る操作を考える。実はそれは、view1 と view2 がちょっと前に model にある値を要求する関数を読んでいて、その答えがシグナルとして返って来たと考えればどうだろう。

分かりにくい例で言うと、HTTP でチャットサーバーを作る時、反応を速くしたいのでサーバーはすぐにレスポンスを返さないで、入力があった瞬間返します。この動作と同じでは無いでしょうか?

つまり2。受けてから見ると、

ハンドラ登録 -> シグナル発生 == 関数呼び出し -> 返り値取得

になるのでは無いでしょうか。ポイントは、関数呼び出しから返り値取得まで、呼び出し側がブロックされる所です。もしも、Gtk シグナルの上にこんな感じのラッパーを被せれば、関数言語的なプログラミングが出来るのではないかと思います。つまり、

void something(GtkWidget *widget, gpointer data)
{
  do_something(data);
}

void node () {
  g_signal_connect(G_OBJECT(widget), "something", G_CALLBACK(something), NULL);
}

という感じのコードが、

void node () {
  while (1) {
    do_something(signal_call(G_OBJECT(widget), "something", NULL));
  }
}

になると嬉しいという事です。あれ?そうかな、また逆に最初のシグナルのコードは、無限ループの方のコードをリフトしてループを暗黙にした物と考える事が出来る。この辺整理してまた考えます。