futures and promises
   HOME

TheInfoList



OR:

In
computer science Computer science is the study of computation, information, and automation. Computer science spans Theoretical computer science, theoretical disciplines (such as algorithms, theory of computation, and information theory) to Applied science, ...
, futures, promises, delays, and deferreds are constructs used for synchronizing program
execution Capital punishment, also known as the death penalty and formerly called judicial homicide, is the state-sanctioned killing of a person as punishment for actual or supposed misconduct. The sentence ordering that an offender be punished in ...
in some
concurrent programming language Concurrent computing is a form of computing in which several computations are executed ''Concurrency (computer science), concurrently''—during overlapping time periods—instead of ''sequentially—''with one completing before the next starts. ...
s. Each is an object that acts as a proxy for a result that is initially unknown, usually because the
computation A computation is any type of arithmetic or non-arithmetic calculation that is well-defined. Common examples of computation are mathematical equation solving and the execution of computer algorithms. Mechanical or electronic devices (or, hist ...
of its value is not yet complete. The term ''promise'' was proposed in 1976 by Daniel P. Friedman and David Wise, and Peter Hibbard called it ''eventual''. A somewhat similar concept ''future'' was introduced in 1977 in a paper by Henry Baker and Carl Hewitt. The terms ''future'', ''promise'', ''delay'', and ''deferred'' are often used interchangeably, although some differences in usage between ''future'' and ''promise'' are treated below. Specifically, when usage is distinguished, a future is a ''read-only'' placeholder view of a variable, while a promise is a writable, single assignment container which sets the value of the future. Notably, a future may be defined without specifying which specific promise will set its value, and different possible promises may set the value of a given future, though this can be done only once for a given future. In other cases a future and a promise are created together and associated with each other: the future is the value, the promise is the function that sets the value – essentially the return value (future) of an asynchronous function (promise). Setting the value of a future is also called ''resolving'', ''fulfilling'', or ''binding'' it.


Applications

Futures and promises originated in
functional programming In computer science, functional programming is a programming paradigm where programs are constructed by Function application, applying and Function composition (computer science), composing Function (computer science), functions. It is a declarat ...
and related paradigms (such as
logic programming Logic programming is a programming, database and knowledge representation paradigm based on formal logic. A logic program is a set of sentences in logical form, representing knowledge about some problem domain. Computation is performed by applyin ...
) to decouple a value (a future) from how it was computed (a promise), allowing the computation to be done more flexibly, notably by parallelizing it. Later, it found use in
distributed computing Distributed computing is a field of computer science that studies distributed systems, defined as computer systems whose inter-communicating components are located on different networked computers. The components of a distributed system commu ...
, in reducing the latency from communication round trips. Later still, it gained more use by allowing writing asynchronous programs in direct style, rather than in continuation-passing style.


Implicit vs. explicit

Use of futures may be ''implicit'' (any use of the future automatically obtains its value, as if it were an ordinary
reference A reference is a relationship between objects in which one object designates, or acts as a means by which to connect to or link to, another object. The first object in this relation is said to ''refer to'' the second object. It is called a ''nam ...
) or ''explicit'' (the user must call a function to obtain the value, such as the get method of in
Java Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
). Obtaining the value of an explicit future can be called ''stinging'' or ''forcing''. Explicit futures can be implemented as a library, whereas implicit futures are usually implemented as part of the language. The original Baker and Hewitt paper described implicit futures, which are naturally supported in the
actor model The actor model in computer science is a mathematical model of concurrent computation that treats an ''actor'' as the basic building block of concurrent computation. In response to a message it receives, an actor can: make local decisions, create ...
of computation and pure
object-oriented programming Object-oriented programming (OOP) is a programming paradigm based on the concept of '' objects''. Objects can contain data (called fields, attributes or properties) and have actions they can perform (called procedures or methods and impl ...
languages like
Smalltalk Smalltalk is a purely object oriented programming language (OOP) that was originally created in the 1970s for educational use, specifically for constructionist learning, but later found use in business. It was created at Xerox PARC by Learni ...
. The Friedman and Wise paper described only explicit futures, probably reflecting the difficulty of efficiently implementing implicit futures on stock hardware. The difficulty is that stock hardware does not deal with futures for primitive data types like integers. For example, an add instruction does not know how to deal with 3 + ''future '' factorial(100000). In pure actor or object languages this problem can be solved by sending ''future '' factorial(100000) the message + /code>, which asks the future to add 3 to itself and return the result. Note that the message passing approach works regardless of when factorial(100000) finishes computation and that no stinging/forcing is needed.


Promise pipelining

The use of futures can dramatically reduce latency in
distributed systems Distributed computing is a field of computer science that studies distributed systems, defined as computer systems whose inter-communicating components are located on different computer network, networked computers. The components of a distribu ...
. For instance, futures enable ''promise pipelining'', as implemented in the languages E and
Joule The joule ( , or ; symbol: J) is the unit of energy in the International System of Units (SI). In terms of SI base units, one joule corresponds to one kilogram- metre squared per second squared One joule is equal to the amount of work d ...
, which was also called ''call-stream'' Also published in ''ACM SIGPLAN Notices'' 23(7). in the language Argus. Consider an expression involving conventional
remote procedure call In distributed computing, a remote procedure call (RPC) is when a computer program causes a procedure (subroutine) to execute in a different address space (commonly on another computer on a shared computer network), which is written as if it were a ...
s, such as:
 t3 := ( x.a() ).c( y.b() )
which could be expanded to
 t1 := x.a();
 t2 := y.b();
 t3 := t1.c(t2);
Each statement needs a message to be sent and a reply received before the next statement can proceed. Suppose, for example, that x, y, t1, and t2 are all located on the same remote machine. In this case, two complete network round-trips to that machine must take place before the third statement can begin to execute. The third statement will then cause yet another round-trip to the same remote machine. Using futures, the above expression could be written
 t3 := (x <- a()) <- c(y <- b())
which could be expanded to
 t1 := x <- a();
 t2 := y <- b();
 t3 := t1 <- c(t2);
The syntax used here is that of the language E, where x <- a() means to send the message a() asynchronously to x. All three variables are immediately assigned futures for their results, and execution proceeds to subsequent statements. Later attempts to resolve the value of t3 may cause a delay; however, pipelining can reduce the number of round-trips needed. If, as in the prior example, x, y, t1, and t2 are all located on the same remote machine, a pipelined implementation can compute t3 with one round-trip instead of three. Because all three messages are destined for objects which are on the same remote machine, only one request need be sent and only one response need be received containing the result. The send t1 <- c(t2) would not block even if t1 and t2 were on different machines to each other, or to x or y. Promise pipelining should be distinguished from parallel asynchronous message passing. In a system supporting parallel message passing but not pipelining, the message sends x <- a() and y <- b() in the above example could proceed in parallel, but the send of t1 <- c(t2) would have to wait until both t1 and t2 had been received, even when x, y, t1, and t2 are on the same remote machine. The relative latency advantage of pipelining becomes even greater in more complicated situations involving many messages. Promise pipelining also should not be confused with pipelined message processing in actor systems, where it is possible for an actor to specify and begin executing a behaviour for the next message before having completed processing of the current message.


Read-only views

In some programming languages such as Oz, E, and AmbientTalk, it is possible to obtain a ''read-only view'' of a future, which allows reading its value when resolved, but does not permit resolving it: * In Oz, the !! operator is used to obtain a read-only view. * In E and AmbientTalk, a future is represented by a pair of values called a ''promise/resolver pair''. The promise represents the read-only view, and the resolver is needed to set the future's value. * In
C++11 C++11 is a version of a joint technical standard, ISO/IEC 14882, by the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC), for the C++ programming language. C++11 replaced the prior vers ...
a std::future provides a read-only view. The value is set directly by using a std::promise, or set to the result of a function call using std::packaged_task or std::async. * In the
Dojo Toolkit Dojo Toolkit (stylized as dōjō toolkit) is an open-source modular JavaScript library (or more specifically JavaScript toolkit) designed to ease the rapid development of cross-platform, JavaScript/ Ajax-based applications and web sites. It was ...
's Deferred API as of version 1.5, a ''consumer-only promise object'' represents a read-only view. * In
Alice ML Alice ML is a general-purpose, high-level, multi-paradigm, functional programming language designed by the Programming Systems Laboratory at Saarland University, Saarbrücken, Germany. It is a dialect of Standard ML, augmented with support ...
, futures provide a ''read-only view'', whereas a promise contains both a future and the ability to resolve the future * In
.NET The .NET platform (pronounced as "''dot net"'') is a free and open-source, managed code, managed computer software framework for Microsoft Windows, Windows, Linux, and macOS operating systems. The project is mainly developed by Microsoft emplo ...
System.Threading.Tasks.Task represents a read-only view. Resolving the value can be done via System.Threading.Tasks.TaskCompletionSource. Support for read-only views is consistent with the
principle of least privilege In information security, computer science, and other fields, the principle of least privilege (PoLP), also known as the principle of minimal privilege (PoMP) or the principle of least authority (PoLA), requires that in a particular abstraction l ...
, since it enables the ability to set the value to be restricted to subjects that need to set it. In a system that also supports pipelining, the sender of an asynchronous message (with result) receives the read-only promise for the result, and the target of the message receives the resolver.


Thread-specific futures

Some languages, such as
Alice ML Alice ML is a general-purpose, high-level, multi-paradigm, functional programming language designed by the Programming Systems Laboratory at Saarland University, Saarbrücken, Germany. It is a dialect of Standard ML, augmented with support ...
, define futures that are associated with a specific thread that computes the future's value. This computation can start either eagerly when the future is created, or lazily when its value is first needed. A lazy future is similar to a
thunk In computer programming Computer programming or coding is the composition of sequences of instructions, called computer program, programs, that computers can follow to perform tasks. It involves designing and implementing algorithms, step-by- ...
, in the sense of a delayed computation. Alice ML also supports futures that can be resolved by any thread, and calls these ''promises''. This use of ''promise'' is different from its use in E as described above. In Alice, a promise is not a read-only view, and promise pipelining is unsupported. Instead, pipelining naturally happens for futures, including ones associated with promises.


Blocking vs non-blocking semantics

If the value of a future is accessed asynchronously, for example by sending a message to it, or by explicitly waiting for it using a construct such as when in E, then there is no difficulty in delaying until the future is resolved before the message can be received or the wait completes. This is the only case to be considered in purely asynchronous systems such as pure actor languages. However, in some systems it may also be possible to attempt to ''immediately'' or ''synchronously'' access a future's value. Then there is a design choice to be made: * the access could block the current thread or process until the future is resolved (possibly with a timeout). This is the semantics of ''dataflow variables'' in the language Oz. * the attempted synchronous access could always signal an error, for example throwing an exception. This is the semantics of remote promises in E. * potentially, the access could succeed if the future is already resolved, but signal an error if it is not. This would have the disadvantage of introducing nondeterminism and the potential for race conditions, and seems to be an uncommon design choice. As an example of the first possibility, in
C++11 C++11 is a version of a joint technical standard, ISO/IEC 14882, by the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC), for the C++ programming language. C++11 replaced the prior vers ...
, a thread that needs the value of a future can block until it is available by calling the wait() or get() member functions. A timeout can also be specified on the wait using the wait_for() or wait_until() member functions to avoid indefinite blocking. If the future arose from a call to std::async then a blocking wait (without a timeout) may cause synchronous invocation of the function to compute the result on the waiting thread.


Related constructs

''Futures'' are a particular case of the synchronization primitive " events," which can be completed only once. In general, events can be reset to initial empty state and, thus, completed as many times as desired. An ''I-var'' (as in the language Id) is a future with blocking semantics as defined above. An ''I-structure'' is a
data structure In computer science, a data structure is a data organization and storage format that is usually chosen for Efficiency, efficient Data access, access to data. More precisely, a data structure is a collection of data values, the relationships amo ...
containing I-vars. A related synchronization construct that can be set multiple times with different values is called an ''M-var''. M-vars support atomic operations to ''take'' or ''put'' the current value, where taking the value also sets the M-var back to its initial ''empty'' state. A ''concurrent logic variable'' is similar to a future, but is updated by unification, in the same way as ''logic variables'' in
logic programming Logic programming is a programming, database and knowledge representation paradigm based on formal logic. A logic program is a set of sentences in logical form, representing knowledge about some problem domain. Computation is performed by applyin ...
. Thus it can be bound more than once to unifiable values, but cannot be set back to an empty or unresolved state. The dataflow variables of Oz act as concurrent logic variables, and also have blocking semantics as mentioned above. A ''concurrent constraint variable'' is a generalization of concurrent logic variables to support constraint logic programming: the constraint may be ''narrowed'' multiple times, indicating smaller sets of possible values. Typically there is a way to specify a thunk that should run whenever the constraint is narrowed further; this is needed to support ''constraint propagation''.


Relations between the expressiveness of different forms of future

Eager thread-specific futures can be straightforwardly implemented in non-thread-specific futures, by creating a thread to calculate the value at the same time as creating the future. In this case it is desirable to return a read-only view to the client, so that only the newly created thread is able to resolve this future. To implement implicit lazy thread-specific futures (as provided by Alice ML, for example) in terms in non-thread-specific futures, needs a mechanism to determine when the future's value is first needed (for example, the WaitNeeded construct in Oz). If all values are objects, then the ability to implement transparent forwarding objects is sufficient, since the first message sent to the forwarder indicates that the future's value is needed. Non-thread-specific futures can be implemented in thread-specific futures, assuming that the system supports message passing, by having the resolving thread send a message to the future's own thread. However, this can be viewed as unneeded complexity. In programming languages based on threads, the most expressive approach seems to be to provide a mix of non-thread-specific futures, read-only views, and either a ''WaitNeeded'' construct, or support for transparent forwarding.


Evaluation strategy

The
evaluation strategy In a programming language, an evaluation strategy is a set of rules for evaluating expressions. The term is often used to refer to the more specific notion of a ''parameter-passing strategy'' that defines the kind of value that is passed to the ...
of futures, which may be termed '' call by future'', is non-deterministic: the value of a future will be evaluated at some time between when the future is created and when its value is used, but the precise time is not determined beforehand and can change from run to run. The computation can start as soon as the future is created (
eager evaluation In a programming language, an evaluation strategy is a set of rules for evaluating expressions. The term is often used to refer to the more specific notion of a ''parameter-passing strategy'' that defines the kind of value that is passed to the ...
) or only when the value is actually needed (
lazy evaluation In programming language theory, lazy evaluation, or call-by-need, is an evaluation strategy which delays the evaluation of an Expression (computer science), expression until its value is needed (non-strict evaluation) and which avoids repeated eva ...
), and may be suspended part-way through, or executed in one run. Once the value of a future is assigned, it is not recomputed on future accesses; this is like the memoization used in call by need. A is a future that deterministically has lazy evaluation semantics: the computation of the future's value starts when the value is first needed, as in call by need. Lazy futures are of use in languages which evaluation strategy is by default not lazy. For example, in
C++11 C++11 is a version of a joint technical standard, ISO/IEC 14882, by the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC), for the C++ programming language. C++11 replaced the prior vers ...
such lazy futures can be created by passing the std::launch::deferred launch policy to std::async, along with the function to compute the value.


Semantics of futures in the actor model

In the actor model, an expression of the form ''future'' is defined by how it responds to an Eval message with environment ''E'' and customer ''C'' as follows: The future expression responds to the Eval message by sending the customer ''C'' a newly created actor ''F'' (the proxy for the response of evaluating ) as a return value ''concurrently'' with sending an Eval message with environment ''E'' and customer ''C''. The default behavior of ''F'' is as follows: * When ''F'' receives a request ''R'', then it checks to see if it has already received a response (that can either be a return value or a thrown exception) from evaluating proceeding as follows: *# If it already has a response ''V'', then *#*If ''V'' is a return value, then it is sent the request ''R''. *#*If ''V'' is an exception, then it is thrown to the customer of the request ''R''. *# If it does not already have a response, then ''R'' is stored in the queue of requests inside the ''F''. * When ''F'' receives the response ''V'' from evaluating , then ''V'' is stored in ''F'' and **If ''V'' is a return value, then all of the queued requests are sent to ''V''. **If ''V'' is an exception, then it is thrown to the customer of each of the queued requests. However, some futures can deal with requests in special ways to provide greater parallelism. For example, the expression 1 + future factorial(n) can create a new future that will behave like the number 1+factorial(n). This trick does not always work. For example, the following conditional expression: : ''if'' m>future factorial(n) ''then'' print("bigger") ''else'' print("smaller") suspends until the future for factorial(n) has responded to the request asking if m is greater than itself.


History

The ''future'' and/or ''promise'' constructs were first implemented in programming languages such as MultiLisp and Act 1. The use of logic variables for communication in concurrent
logic programming Logic programming is a programming, database and knowledge representation paradigm based on formal logic. A logic program is a set of sentences in logical form, representing knowledge about some problem domain. Computation is performed by applyin ...
languages was quite similar to futures. These began in ''Prolog with Freeze'' and ''IC Prolog'', and became a true concurrency primitive with Relational Language, Concurrent
Prolog Prolog is a logic programming language that has its origins in artificial intelligence, automated theorem proving, and computational linguistics. Prolog has its roots in first-order logic, a formal logic. Unlike many other programming language ...
, guarded Horn clauses (GHC), Parlog, Strand, Vulcan, Janus, Oz-Mozart, Flow Java, and
Alice ML Alice ML is a general-purpose, high-level, multi-paradigm, functional programming language designed by the Programming Systems Laboratory at Saarland University, Saarbrücken, Germany. It is a dialect of Standard ML, augmented with support ...
. The single-assignment ''I-var'' from dataflow programming languages, originating in Id and included in Reppy's '' Concurrent ML'', is much like the concurrent logic variable. The promise pipelining technique (using futures to overcome latency) was invented by Barbara Liskov and Liuba Shrira in 1988, and independently by Mark S. Miller, Dean Tribble and Rob Jellinghaus in the context of Project Xanadu circa 1989. The term ''promise'' was coined by Liskov and Shrira, although they referred to the pipelining mechanism by the name ''call-stream'', which is now rarely used. Both the design described in Liskov and Shrira's paper, and the implementation of promise pipelining in Xanadu, had the limit that promise values were not first-class: an argument to, or the value returned by a call or send could not directly be a promise (so the example of promise pipelining given earlier, which uses a promise for the result of one send as an argument to another, would not have been directly expressible in the call-stream design or in the Xanadu implementation). It seems that promises and call-streams were never implemented in any public release of Argus, the programming language used in the Liskov and Shrira paper. Argus development stopped around 1988. The Xanadu implementation of promise pipelining only became publicly available with the release of the source code for Udanax Gold in 1999, and was never explained in any published document. The later implementations in Joule and E support fully first-class promises and resolvers. Several early actor languages, including the Act series, supported both parallel message passing and pipelined message processing, but not promise pipelining. (Although it is technically possible to implement the last of these features in the first two, there is no evidence that the Act languages did so.) After 2000, a major revival of interest in futures and promises occurred, due to their use in responsiveness of user interfaces, and in web development, due to the request–response model of message-passing. Several mainstream languages now have language support for futures and promises, most notably popularized by FutureTask in Java 5 (announced 2004) and the async/await constructions in .NET 4.5 (announced 2010, released 2012) largely inspired by the ''asynchronous workflows'' of F#, which dates to 2007. This has subsequently been adopted by other languages, notably Dart (2014), Python (2015), Hack (HHVM), and drafts of ECMAScript 7 (JavaScript), Scala, and C++ (2011).


List of implementations

Some programming languages are supporting futures, promises, concurrent logic variables, dataflow variables, or I-vars, either by direct language support or in the standard library.


List of concepts related to futures and promises by programming language

* ABCL/f *
Alice ML Alice ML is a general-purpose, high-level, multi-paradigm, functional programming language designed by the Programming Systems Laboratory at Saarland University, Saarbrücken, Germany. It is a dialect of Standard ML, augmented with support ...
* AmbientTalk (including first-class resolvers and read-only promises) * C++, starting with
C++11 C++11 is a version of a joint technical standard, ISO/IEC 14882, by the International Organization for Standardization (ISO) and International Electrotechnical Commission (IEC), for the C++ programming language. C++11 replaced the prior vers ...
: std::future and std::promise ** Compositional C++ * Crystal (programming language) * Dart (with ''Future''/''Completer'' classes and the keywords ''await'' and ''async'') *
Elm (programming language) Elms are deciduous and semi-deciduous trees comprising the genus ''Ulmus'' in the family Ulmaceae. They are distributed over most of the Northern Hemisphere, inhabiting the temperate and tropical- montane regions of North America and Eurasia, ...
via the ''Task'' module * Glasgow
Haskell Haskell () is a general-purpose, statically typed, purely functional programming language with type inference and lazy evaluation. Designed for teaching, research, and industrial applications, Haskell pioneered several programming language ...
(I-vars and M-vars only) * Id (I-vars and M-vars only) * Io *
Java Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
via or *
JavaScript JavaScript (), often abbreviated as JS, is a programming language and core technology of the World Wide Web, alongside HTML and CSS. Ninety-nine percent of websites use JavaScript on the client side for webpage behavior. Web browsers have ...
as of
ECMAScript ECMAScript (; ES) is a standard for scripting languages, including JavaScript, JScript, and ActionScript. It is best known as a JavaScript standard intended to ensure the interoperability of web pages across different web browsers. It is stan ...
2015, and via the keywords async and await since ECMAScript 2017 * Lucid (dataflow only) * Some Lisps **
Clojure Clojure (, like ''closure'') is a dynamic programming language, dynamic and functional programming, functional dialect (computing), dialect of the programming language Lisp (programming language), Lisp on the Java (software platform), Java platfo ...
** MultiLisp *
.NET The .NET platform (pronounced as "''dot net"'') is a free and open-source, managed code, managed computer software framework for Microsoft Windows, Windows, Linux, and macOS operating systems. The project is mainly developed by Microsoft emplo ...
via ''Task''s ** C#, since .NET Framework 4.5, via the keywords async and await * Kotlin, however kotlin.native.concurrent.Future is only usually used when writing Kotlin that is intended to run natively * Nim * Oxygene * Oz version 3 * Pythonbr>concurrent.futures
since 3.2, as proposed by th
PEP 3148
and Python 3.5 added async and await * R (promises for lazy evaluation, still single threaded) * Racket * Raku *
Rust Rust is an iron oxide, a usually reddish-brown oxide formed by the reaction of iron and oxygen in the catalytic presence of water or air moisture. Rust consists of hydrous iron(III) oxides (Fe2O3·nH2O) and iron(III) oxide-hydroxide (FeO(OH) ...
(usually achieved via .await) * Scala vi
scala.concurrent package
* Scheme *
Squeak Squeak is an object-oriented, class-based, and reflective programming language. It was derived from Smalltalk-80 by a group that included some of Smalltalk-80's original developers, initially at Apple Computer, then at Walt Disney Imaginee ...
Smalltalk Smalltalk is a purely object oriented programming language (OOP) that was originally created in the 1970s for educational use, specifically for constructionist learning, but later found use in business. It was created at Xerox PARC by Learni ...
* Strand *
Swift Swift or SWIFT most commonly refers to: * SWIFT, an international organization facilitating transactions between banks ** SWIFT code * Swift (programming language) * Swift (bird), a family of birds It may also refer to: Organizations * SWIF ...
(only via third-party libraries) *
Visual Basic Visual Basic is a name for a family of programming languages from Microsoft. It may refer to: * Visual Basic (.NET), the current version of Visual Basic launched in 2002 which runs on .NET * Visual Basic (classic), the original Visual Basic suppo ...
11 (via the keywords ''Async'' and ''Await'') Languages also supporting promise pipelining include: * E *
Joule The joule ( , or ; symbol: J) is the unit of energy in the International System of Units (SI). In terms of SI base units, one joule corresponds to one kilogram- metre squared per second squared One joule is equal to the amount of work d ...


List of library-based implementations of futures

* For
Common Lisp Common Lisp (CL) is a dialect of the Lisp programming language, published in American National Standards Institute (ANSI) standard document ''ANSI INCITS 226-1994 (S2018)'' (formerly ''X3.226-1994 (R1999)''). The Common Lisp HyperSpec, a hyperli ...
: ** Blackbird ** Eager Future2 ** lparallel ** PCall * For C++: ** Boost library ** Dlib ** Folly ** HPX **
POCO C++ Libraries In software engineering Software engineering is a branch of both computer science and engineering focused on designing, developing, testing, and maintaining Application software, software applications. It involves applying engineering design pr ...
(Active Results) ** Qt ** Seastar ** stlab * For C# and other
.NET The .NET platform (pronounced as "''dot net"'') is a free and open-source, managed code, managed computer software framework for Microsoft Windows, Windows, Linux, and macOS operating systems. The project is mainly developed by Microsoft emplo ...
languages: The Parallel Extensions library * For
Groovy ''Groovy'' (or, less commonly, ''groovie'' or ''groovey'') is a slang colloquialism popular during the 1960s and 1970s. It is roughly synonymous with words such as "excellent", "fashionable", or "amazing", depending on context. History The word ...
: GPars * For
JavaScript JavaScript (), often abbreviated as JS, is a programming language and core technology of the World Wide Web, alongside HTML and CSS. Ninety-nine percent of websites use JavaScript on the client side for webpage behavior. Web browsers have ...
: ** Cujo.js' when.js provides promises conforming to the Promises/A+ 1.1 specification ** The
Dojo Toolkit Dojo Toolkit (stylized as dōjō toolkit) is an open-source modular JavaScript library (or more specifically JavaScript toolkit) designed to ease the rapid development of cross-platform, JavaScript/ Ajax-based applications and web sites. It was ...
supplies promises and Twisted style deferreds ** MochiKit inspired by Twisted's Deferreds *
jQuery's
/api.jquery.com/category/deferred-object/ Deferred Objectis based on th
CommonJS Promises/A
design. ** AngularJS **
node In general, a node is a localized swelling (a "knot") or a point of intersection (a vertex). Node may refer to: In mathematics * Vertex (graph theory), a vertex in a mathematical graph *Vertex (geometry), a point where two or more curves, lines ...
-promise ** Q, by Kris Kowal, conforms to Promises/A+ 1.1 ** RSVP.js, conforms to Promises/A+ 1.1 ** YUI's promise class conforms to the Promises/A+ 1.0 specification. ** Bluebird, by Petka Antonov ** The Closure Library'
promise
package conforms to the Promises/A+ specification. ** Se
Promise/A+'s
list for more implementations based on the Promise/A+ design. * For
Java Java is one of the Greater Sunda Islands in Indonesia. It is bordered by the Indian Ocean to the south and the Java Sea (a part of Pacific Ocean) to the north. With a population of 156.9 million people (including Madura) in mid 2024, proje ...
: ** JDeferred, provides deferred-promise API and behavior similar to jQuery.Deferred object ** ParSeq provides task-promise API ideal for asynchronous pipelining and branching, maintained by
LinkedIn LinkedIn () is an American business and employment-oriented Social networking service, social network. It was launched on May 5, 2003 by Reid Hoffman and Eric Ly. Since December 2016, LinkedIn has been a wholly owned subsidiary of Microsoft. ...
* For Lua: ** The cqueue

module contains a Promise API. * For
Objective-C Objective-C is a high-level general-purpose, object-oriented programming language that adds Smalltalk-style message passing (messaging) to the C programming language. Originally developed by Brad Cox and Tom Love in the early 1980s, it was ...
: MAFuture, RXPromise, ObjC-CollapsingFutures, PromiseKit, objc-promise, OAPromise, * For
OCaml OCaml ( , formerly Objective Caml) is a General-purpose programming language, general-purpose, High-level programming language, high-level, Comparison of multi-paradigm programming languages, multi-paradigm programming language which extends the ...
: Lazy module implements lazy explicit futures * For
Perl Perl is a high-level, general-purpose, interpreted, dynamic programming language. Though Perl is not officially an acronym, there are various backronyms in use, including "Practical Extraction and Reporting Language". Perl was developed ...
: Future, Promises, Reflex, Promise::ES6, and Promise::XS * For PHP: React/Promise * For Python: ** Built-in implementation ** pythonfutures ** Twisted's Deferreds * For R: ** future, implements an extendable future API with lazy and eager synchronous and (multicore or distributed) asynchronous futures * For
Ruby Ruby is a pinkish-red-to-blood-red-colored gemstone, a variety of the mineral corundum ( aluminium oxide). Ruby is one of the most popular traditional jewelry gems and is very durable. Other varieties of gem-quality corundum are called sapph ...
: ** Concurrent Ruby ** Promise gem ** libuv gem, implements promises ** Celluloid gem, implements futures ** future-resource * For
Rust Rust is an iron oxide, a usually reddish-brown oxide formed by the reaction of iron and oxygen in the catalytic presence of water or air moisture. Rust consists of hydrous iron(III) oxides (Fe2O3·nH2O) and iron(III) oxide-hydroxide (FeO(OH) ...
: ** futures-rs * For Scala: ** Twitter's util library * For
Swift Swift or SWIFT most commonly refers to: * SWIFT, an international organization facilitating transactions between banks ** SWIFT code * Swift (programming language) * Swift (bird), a family of birds It may also refer to: Organizations * SWIF ...
: ** Async framework, implements C#-style async/non-blocking await ** FutureKit, implements a version for Apple GCD ** FutureLib, pure Swift 2 library implementing Scala-style futures and promises with TPL-style cancellation ** Deferred, pure Swift library inspired by OCaml's Deferred ** BrightFutures ** SwiftCoroutine * For Tcl: tcl-promise


Coroutines

Futures can be implemented in
coroutine Coroutines are computer program components that allow execution to be suspended and resumed, generalizing subroutines for cooperative multitasking. Coroutines are well-suited for implementing familiar program components such as cooperative task ...
s or generators, resulting in the same evaluation strategy (e.g., cooperative multitasking or lazy evaluation).


Channels

Futures can easily be implemented in channels: a future is a one-element channel, and a promise is a process that sends to the channel, fulfilling the future. This allows futures to be implemented in concurrent programming languages with support for channels, such as CSP and Go. The resulting futures are explicit, as they must be accessed by reading from the channel, rather than only evaluation.


See also

* Fiber (computer science) * Futex * Pyramid of doom (programming), a design antipattern avoided by promises


References


External links


Concurrency patterns presentation
given a
scaleconf

Future Value
an
Promise Pipelining
at the Portland Pattern Repository
Easy Threading with Futures
in Python {{DEFAULTSORT:Futures and promises Inter-process communication Actor model (computer science)