Aller au contenu principal

Future パターン


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
  • Act1
  • Alice ML
  • AmbientTalk (first-class resolvers と read-only promises を含む)
  • C++ (C++11以降のstd::futurestd::promise、C++20以降のco_await)
    • μC++
  • C# (C# 5.0以降のasync/await構文)
  • Concurrent Prolog
  • Dart (Future/Completerクラス、async/awaitキーワード)
  • Flow Java
  • Glasgow Haskell (I-vars and M-vars only)
  • GHC
  • Id (プログラミング言語) (I-vars and M-vars only)
  • Io
  • Java: Java 1.5以降のjava.util.concurrent.Future
  • JavaScript (ECMAScript): ES2015 (ES6) 以降のPromise、ES2017以降のasync/await構文
  • KL1(その実装としてKLICがある)
  • LISP系言語
    • Clojure
    • MultiLisp
    • Scheme
  • Lucid (データフローのみ)
  • Oxygene
  • 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::promise
    • Dlib C++ Library
    • マイクロソフトによる同時実行ランタイム (ConCRT) の並列パターンライブラリにおけるconcurrency::task
  • 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

Text submitted to CC-BY-SA license. Source: Future パターン by Wikipedia (Historical)


ghbass