クロージャーだと苦労するんじゃ?(ダジャレ)


closureで継続(continuation)を実現する技法ってあるじゃないですか。
例えば次の記事は私が5年以上前に書いてますね。


C#2.0時代のゲームプログラミング(49) 〜 delegateを用いたcontinuation
http://d.hatena.ne.jp/yaneurao/20070207


上の技法は私は10年ぐらい前にclosureを使い出したころに自力で発見しましたが、まあ、いまや常識ですよね。それで最近、それに似た話題があったので取り上げてみます。

ここで再度認識して欲しいのは、node.js の素晴らしさは「クライアント側で皆が使っているJavaScriptでプログラムが書ける」という部分などにあるのではない、という点だ。node.js がこれほど多くの支持者を得ているのは「本来記述が煩雑になりやすい非同期処理をJavaScriptの無名関数を利用して書きやすく・読みやすくすることにより、イベント駆動型のプログラミングを多くのプログラマーにとって手の届くものにした」点にあるのだ。

前にも説明した通り、イベント駆動型のプログラミングは、直感的にフローを把握しにくいという理由で多くのプログラマーたちに敬遠されて来た。特にクロージャをサポートしていない言語の場合、非同期 API を呼び出すプログラムと、イベントを処理する部分のプログラムが離れたところに記述されてしまうため、プログラムがとても読みにくくなる、という性質があった。

node.js と thread hog の話(3) (Life is beautiful)
http://satoshi.blogs.com/life/2012/10/closure.html

先日の「node.js と thread hog の話」には、たくさんのコメントをいただいたが、やはり「イベント駆動型」のプログラミングには抵抗がある人も多いようだ。そこで、JavaScript の無名関数を使ったイベント駆動型のプログラミングの可読性が悪くないことを示すために、「朝7時に目覚まし時計をかけて眠りにつき、朝ご飯を食べ終わったら会社に行く」という典型的な「サラリーマンの朝」をイベント駆動型のJavaScriptで記述してみた。


node.js で「サラリーマンの朝」をプログラムしてみる
http://satoshi.blogs.com/life/2012/10/%E3%82%A4%E3%83%99%E3%83%B3%E3%83%88%E9%A7%86%E5%8B%95%E5%9E%8B%E3%81%A7%E7%A7%81%E3%81%AE%E6%9C%9D%E3%82%92%E3%83%97%E3%83%AD%E3%82%B0%E3%83%A9%E3%83%A0%E3%81%97%E3%81%A6%E3%81%BF%E3%82%8B.html

それで書かれていたコードがこれなのですが…。



中島さんは「可読性が悪くない」とおっしゃるわけですが、{ }が何重にもネストしていて私にはすこぶる見にくいです。無論、従来のイベント駆動型のプログラムに比べますと一箇所に書けているという意味はありますが、私が思うにこの手のプログラムはC# 5.0のasync/awaitのように書けるのが当たり前であって、こんな何重にもネストしている汚らしいプログラムを、5年前ならいざ知らず、いまごろ「可読性が悪くない」と自慢気に出してこられましてもというのはあります。


それで話を戻しまして、じゃあ、JavaScriptでasync/awaitのようなことは出来るのかと言いますと、async/awaitを継続渡しスタイル(CPS)に変換するようなtranslatorを使うのがひとつの方法だと思います。


非同期処理をシンプルに書けるJavaScriptライブラリ「TameJS」
http://news.mynavi.jp/news/2011/08/01/007/index.html


公式
http://tamejs.org/


GitHub
https://github.com/maxtaco/tamejs



ただ、変換するためのオーバーヘッドがあるので負荷が問題になるようなところで(node.jsのようにサーバーサイドでJavaScriptを動かす場合は特に)変換して実行するわけにはいかないというのはあります。


TameJSに関してはいまひとつ知名度が高くないように思います。それほど大きな規模の非同期プログラムをJavaScriptで書くのでなければ、こんなライブラリいちいち使うほどではないというのもありますし、そもそもそんな大きな規模の非同期プログラムをJavaScriptで書かないというのもあります。まあ、そんな理由で私には今後普及するとも思えません。


あとは、yieldが使えるならダイレクトにasync/await相当の処理を実装する方法もあります。



WinRT の async/await コーディングがおもしろい(のでJavaScriptで真似してみた) (てっく煮ブログ)
http://tech.nitoyon.com/ja/blog/2011/09/29/async-await-in-js/


ただ、yieldはJavaScript 1.7でしか使えず、現状ほとんどのブラウザでのサポートは非常にさぶーい状況です。HTML5標準に少しでも近づけようという苛烈なブラウザ戦争が行われておりますが、最新のJavaScriptに準拠させようという努力をもう少しでもしていただきたいと切に願う次第です。ついでに言えばJavaScriptみたいな糞仕様の言語、早く無くなっ・・おっと誰かが来たようです。