Future パターン
この記事には独自研究が含まれているおそれがあります。 |
future, promise, delay とは、プログラミング言語における並列処理のデザインパターン。何らかの処理を別のスレッドで処理させる際、その処理結果の取得を必要になるところまで後回しにする手法。処理をパイプライン化させる。1977年に考案され、現在ではほとんどのプログラミング言語で利用可能。
概要
編集カール・ヒューイットは、2つの点で future の方が promise よりも適した用語であるとしている。第一に promise(約束)は必ずしも将来の時点のことを意味しないため、future(未来)よりも曖昧である。第二に promise は単なる言語表現だが、future は現物(actuals)に対する先物(futures)という意味もある(つまり、実際の物に対する代用品)。
future という構文が最初に紹介されたのは1977年、ヘンリー・ベイカーとカール・ヒューイットの論文でのことであった。一方 promise という用語は、1976年にダニエル・P・フリードマンとデビッド・ワイズが提案し、最終的にピーター・ヒバードが呼んだものである。future (promise) の使用により、分散システムにおける遅延を劇的に減少させることができる。例えばアクターモデルのようにメッセージのパイプライン化が可能であり、これをE言語やAlice MLでは promise pipelining と呼ぶ[1]。
パイプライン化
編集一般的な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[1]
- Act1
- Alice ML
- AmbientTalk (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[2]/Completer[3]クラス、async/await[4]キーワード)
- Flow Java
- Glasgow Haskell (I-vars and M-vars only)
- GHC
- Id (プログラミング言語) (I-vars and M-vars only)
- Io [5]
- Java: Java 1.5以降の
java.util.concurrent.Future
- JavaScript (ECMAScript): ES2015 (ES6) 以降のPromise、ES2017以降のasync/await構文
- KL1(その実装としてKLICがある)
- LISP系言語
- Lucid (データフローのみ)
- Oxygene
- Oz version 3[7](その実装としてMozart Programming Systemがある)
- Python 3.2, PEP 3148 で提案
- R (promises for lazy evaluation - still single threaded)
- Racket[8]
- Scala
- Visual Basic .NET (VB.NET 11以降のAsync/Await構文)
- C#やVB.NETなどの.NET言語全般: .NET 4以降のタスク並列ライブラリ (Parallel Extensions)
- Nim[9]
加えて、promise pipelining をサポートする言語:
非標準ライブラリによる実装:
- Common Lisp: Eager Future2, PCall
- C++:
- Boost C++ライブラリにおける
boost::future
[10]とboost::promise
[11] - Dlib C++ Library
- マイクロソフトによる同時実行ランタイム (ConCRT) の並列パターンライブラリにおける
concurrency::task
[12]
- Boost C++ライブラリにおける
- 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.
脚注
編集- ^ Kenjiro Taura, Satoshi Matsuoka, and Akinori Yonezawa (1994). "ABCL/f: A Future-Based Polymorphic Typed Concurrent Object-Oriented Language -- Its Design and Implementation.". In Proceedings of the DIMACS workshop on Specification of Parallel Algorithms, number 18 in Dimacs Series in Discrete Mathematics and Theoretical Computer Science. American Mathematical Society. pp. 275–292.
- ^ “Future class - dart:async library - Dart API”. 2021年6月17日閲覧。
- ^ “Completer class - dart:async library - Dart API”. 2021年6月17日閲覧。
- ^ “Asynchronous programming: futures, async, await”. 2021年6月17日閲覧。
- ^ Steve Dekorte (2006, 2007, 2008). “Io, The Programming Language”. 2008年5月5日閲覧。
- ^ Rich Hickey (2009年). “changes.txt at 1.1.x from richhickey's clojure”. 2013年4月14日閲覧。
- ^ Seif Haridi; Nils Franzen. “Tutorial of Oz”. MOzart Global User Library. 12 April 2011閲覧。
- ^ “Parallelism with Futures”. PLT. 02 March 2012閲覧。
- ^ “asyncfutures”. nim-lang.org. 2021年6月12日閲覧。
- ^ Boost.Future
- ^ Boost.Promise
- ^ Task Parallelism (Concurrency Runtime) | Microsoft Docs