現在進行中の処理と未来の値を指し示すfuture/promise/deferred

Future::Qモジュールを書いた時に他のfuture実装についてもいくつか調べたのでメモ。

futureは(バックグラウンドで)現在進行中の処理と、それが終わったあかつきに得られるであろう結果の値を指し示す(というか保持する)オブジェクト。


言語によってfutureとかpromiseとかdeferredとか呼ばれるけど、コンセプトとしてはどれも同じようなものなのだと思う。ここでは総称して"future"という言葉を使うことにする。

futureの使い方には主に次の2種類がある。

ブロッキングスタイル
futureから値を取り出すAPIが存在する(get()メソッドなど)。処理が進行中で値が未確定の場合、処理が終わるまでブロックする。
ノンブロッキングスタイル
futureにコールバック関数を登録するAPIが存在する(then()メソッドなど)。処理が終了したらコールバック関数が実行される。登録時に既に処理が終了していたらコールバック関数はすぐに実行される。

futureによっては、これらのスタイルをどちらも利用可能なAPIが設定されていたりする。

このスタイルによっていくつかのfuture実装を分類してみると、以下のような感じだろうか。

Qは"Promises/A+仕様"を実装したJavaScriptモジュール。em-promise, celluloid-promiseはQと同等の機能をRubyのEventMachineやCelluloidの枠組みで使えるようにしたもの(だと思う)。

IO::Async::FutureはFutureのサブクラスで、IO::Asyncのイベントループを使ってget()メソッドをブロックさせるようにしたもの。元のFutureにはget()時にブロックする機能は無い。

Scalaはさっぱり分からないけど、APIリファレンスを見るかぎり、com.twitter.util.Futureは両対応型のオブジェクトだと思う。もしかすると、PerlのFutureモジュールはこれのAPIを参考にしたのかもしれない。