Future パターン

future, promise, delay とは、プログラミング言語における並列処理のデザインパターン。何らかの処理を別のスレッドで処理させる際、その処理結果の取得を必要になるところまで後回しにする手法。処理をパイプライン化させる。1977年に考案され、現在ではほとんどのプログラミング言語で利用可能。

 概要 
カール・ヒューイットは、2つの点で future の方が promise よりも適した用語であるとしている。第一に promise（約束）は必ずしも将来の時点のことを意味しないため、future（未来）よりも曖昧である。第二に promise は単なる言語表現だが、future は現物（actuals）に対する先物（futures）という意味もある（つまり、実際の物に対する代用品）。

future という構文が最初に紹介されたのは1977年、とカール・ヒューイットの論文でのことであった。一方 promise という用語は、1976年にとデビッド・ワイズが提案し、最終的にピーター・ヒバードが呼んだものである。future (promise) の使用により、分散システムにおける遅延を劇的に減少させることができる。例えばアクターモデルのようにメッセージのパイプライン化が可能であり、これをやでは promise pipelining と呼ぶ。

 パイプライン化 
一般的なRPCで次のような式を考える。
 t3 := (x.a()).c(y.b())

これは、次のように展開できる。
 t1 := x.a(); t2 := y.b(); t3 := t1.c(t2)

これを解釈すると、t1 および t2 の値が定まらないと t3 の値は計算できない。future を使うとこの式が次のように表される。
 t3 := future (future x.a()).c(future y.b())

これを展開すると次のようになる。
 t1 := future x.a(); t2 := future y.b(); t3 := future t1.c(t2)

このようにすると t3 は即座に計算される。ただし、t3 から情報を得ようとすると待たされる。

 実装 
future構文は MultiLisp や Act1 といったプログラミング言語で実装された。並行論理プログラミング言語における論理変数もよく似ている。これは当初 Prolog with Freeze や IC Prolog で使われ、Relational Language、Concurrent Prolog、PARLOG、GHC、KL1、Strand、Vulcan、Janus、Mozart/Oz、Flow Java、Alice といった言語で真の並行性プリミティブとなった。Concurrent ML のような単一代入規則型データフロー言語の I-var は並行論理変数とよく似ている。

future による遅延最小化のようなパイプライン化技法はまずアクターモデルで生み出され、1988年にバーバラ・リスコフが再発明し、1989年ごろにはザナドゥ計画でも再発明されている。

future, promise, 並行論理変数, データフロー変数, I-var をサポートする言語:
 ABCL/f
 Act1

  (first-class resolvers と read-only promises を含む)
 C++ (C++11以降のstd::futureとstd::promise、C++20以降のco_await)

 C# (C# 5.0以降のasync/await構文)
 Concurrent Prolog
 Dart (Future/Completerクラス、async/awaitキーワード)

 Glasgow Haskell (I-vars and M-vars only)
 GHC
  (I-vars and M-vars only)
 Io 
 Java: Java 1.5以降の 
 JavaScript (ECMAScript): ES2015 (ES6) 以降のPromise、ES2017以降のasync/await構文
 KL1（その実装としてKLICがある）
 LISP系言語
 Clojure

 Scheme
 Lucid (データフローのみ)

 Oz version 3（その実装としてMozart Programming Systemがある）
 Python 3.2, PEP 3148 で提案
 R (promises for lazy evaluation - still single threaded)
 Racket
 Scala
 Visual Basic .NET (VB.NET 11以降のAsync/Await構文)
 C#やVB.NETなどの.NET言語全般: .NET 4以降のタスク並列ライブラリ (Parallel Extensions)
Nim

加えて、promise pipelining をサポートする言語:
Joule言語 
E言語

非標準ライブラリによる実装:
 Common Lisp: Eager Future2, PCall 
 C++:
 Boost C++ライブラリにおけるboost::futureBoost.Futureとboost::promiseBoost.Promise
 Dlib C++ Library
 マイクロソフトによる同時実行ランタイム (ConCRT) のにおけるconcurrency::taskTask Parallelism (Concurrency Runtime) | Microsoft Docs
 Groovy: GPars
 JavaScript:
 Cujo.js - CommonJS Promises/A に基づく promise を when.js が提供
 Dojo Toolkit - promises と Twisted style Deferred を提供
 jQuery - CommonJS Promises/A に基づく物を Deferred Object で提供
 node-promise
 Q
 RSVP.js
 Java: JQuery.Deferred に似た振る舞いを JDeferred の Deferred/Promise API が提供
 Objective-C: MAFuture (reference), PromiseKit, Promises
 OCaml: Lazy モジュールが lazy explicit future を実装
 Perl: Future, Reflex 
 PHP: React/Promise
 Python: pythonfutures, Twisted's Deferreds
 Ruby: Promise gem
 Swift: FutureKit, BrightFutures, PromiseKit, Promises

 参考文献 
 Henry Baker and Carl Hewitt The Incremental Garbage Collection of Processes Proceeding of the Symposium on Artificial Intelligence Programming Languages. SIGPLAN Notices 12, August 1977.
 Henry Lieberman. Thinking About Lots of Things at Once without Getting Confused: Parallelism in Act 1 MIT AI memo 626.  May 1981.
 Henry Lieberman. A Preview of Act 1 MIT AI memo 625.  June 1981.

 脚注 

 関連項目 
 評価戦略#未来呼び
 ファイバー (コンピュータ)
 コルーチン
 Async/await

 外部リンク 
Portland Pattern Repository
 Future Value
 Promise Pipelining 

Category:分散処理
Category:並行計算
Category:アクターモデル
Category:プログラミング言語の構文