Future与promise
引用

1 2  Daniel Friedman; David Wise. . International Conference on Parallel Processing: 263–272. 1976. We have proposed a new semantics for cons and its extractor functions first and rest which avoids the construction of those portions of structures that are never accessed. ……
Using the function cons as a paradigm of structure-creating functions, we briefly explain its semantics. When cons is invoked by the user, the value returned is a pointer to a newly built structure. Rather than evaluate the arguments to cons and create the complete structure, we create a structure consisting of two suspensions. A suspension consists of a reference to the form whose evaluation was deferred and a reference to the environment of variable bindings in which the suspension was originally created. ……
When either of the functions first or rest is invoked, the following events occur. A designated field of the argument is checked to determine if it contains a suspension (suspensions are flagged and easily distinguished); if not, then its contents is returned. If a suspension is present, then the evaluator is invoked upon the designated form within the preserved environment. The result is stored back in the designated field in place of the suspension (for next time); and the value is returned as a final result. ……
As a result of suspending, evaluations are delayed as long as possible. ……
A fortunate side-effect of suspending the creation of data structures is the ability to deal with infinite structures. Consider the list defined (but never completely constructed) by the invocation of <terms[O]> where
  <terms[n]> ≡ <cons[<recip[<square[n]>]>
                     <terms[<addl[n]>]> ]> .
That list, the reciprocals of the squares of all the positive integers, might be familiar since its sum, excluding the first term, converges to π2/6. Suppose that z were bound to the result of <terms[O]>; in fact, because of the suspending cons, z is initially bound only to a "promise" of this result.
↑  Hibbard, Peter. . New Directions in Algorithmic Languages, (ed.) Stephen A. Schuman, IRIA, 1976. 1976.
↑  Henry Baker; Carl Hewitt. . Proceedings of the Symposium on Artificial Intelligence Programming Languages,. ACM Sigplan Notices 12, 8: 55–59. August 1977  [2024-01-26]. （原始内容存档于2024-04-12）. In this paper we consider an "eager beaver" evaluator for an applicative programming language which starts evaluating every subexpression as soon as possible, and in parallel. This is done through the mechanism of futures, which are roughly Algol-60 "thunks" which have their own evaluator process ("thinks"?). (Friedman and Wise [10] call futures "promises", while Hibbard [13] calls them "eventuals".) When an expression is given to the evaluator by the user, a future for that expression is returned which is a promise to deliver the value of that expression at some later time, if the expression has a value. A process is created for each new future which immediately starts to work evaluating the given expression. ……
The intuitive semantics associated with a future is that it runs asynchronously with its parent's evaluation. This effect can be achieved by either assigning a different processor to each future, or by multiplexing all of the futures on a few processors. Given one such implementation, the language can easily be extended with a construct having the following form: "(EITHER <e1> <e2> … <en>)" means evaluate the expressions <ei> in parallel and return the value of "the first one that finishes".
1 2 3  
Halstead, Robert H. Jr. . ACM Transactions on Programming Languages and Systems. October 1985, 7 (4): 501–538. S2CID 1285424. doi:10.1145/4472.4478 . Multilisp's principal construct for both creating tasks and synchronizing among them is the future. The construct (future X) immediately returns a future for the value of the expression X and concurrently begins evaluating X. When the evaluation of X yields a value, that value replaces the future. The future is said to be initially undetermined; it becomes determined when its value has been computed. An operation (such as addition) that needs to know the value of an undetermined future will be suspended until the future becomes determined, but many operations, such as assignment and parameter passing, do not need to know anything about the values of their operands and may be performed quite comfortably on undetermined futures. ……
The future construct in Multilisp, for example, offers a way to introduce parallelism that fits very nicely with the principal program operation of Multilisp — expression evaluation. Also, no special care is required to use a value generated by future. Synchronization between the producer and the users of a future’s value is implicit, freeing the programmer’s mind from a possible source of concern.
1 2 3  Barbara Liskov; Liuba Shrira. . . ACM: 260–267. 1988  [2024-01-26]. ISBN 0-89791-269-1. doi:10.1145/53990.54016. （原始内容存档于2024-01-26）. Promises were designed to support an efficient asynchronous remote procedure call mechanism for use by components of a distributed program. A promise is a place holder for a value that will exist in the future. It is created at the time a call is made. The call computes the value of the promise, running in parallel with the program that made the call. When it completes, its results are stored in the promise and can then be “claimed” by the caller. ……
Call-streams allow a sender to make a sequence of calls to a receiver without waiting for replies. The stream guarantees that the calls will be delivered to the receiver in the order they were made and that the replies from the receiver will be delivered to the sender in call order. ……
The design of promises was influenced by the future mechanism of MultiLisp[5]. Like futures, promises allow the result of a call to be picked up later. However, promises extend futures in several ways: Promises are strongly typed and thus avoid the need for runtime checking to distinguish them from ordinary values. They allow exceptions from the called procedure to be propagated in a convenient manner. Finally, they are integrated with the call-stream mechanism and address problems such as node failures and network partitions that do not arise in a single-machine environment. ……
There are two reasons for using stream calls instead of RPCs: they allow the caller to run in parallel with the sending and processing of the call, and they reduce the cost of transmitting the call and reply messages. RPCs and their replies are sent over the network immediately, to minimize the delay for a call. Stream calls and their replies, however, are buffered and sent when convenient; in the case of sends, normal replies can be omitted. Buffering allows us to amortize the overhead of kernel calls and the transmission delays for messages over several calls, especially for small calls and replies.  Also published in ACM SIGPLAN Notices 23(7).
↑  Kisalaya Prasad, Avanti Patil, Heather Miller. .   [2024-03-11]. （原始内容存档于2024-03-03）.
↑  Domenico Talia. . 1990  [2024-03-13]. （原始内容存档于2024-03-13）. Concurrent logic languages are born from a new interpretation of Horn clauses, the process interpretation. According to this interpretation, an atomic goal ← C can be viewed as a process, a conjunctive goal ← C1, …, Cn, as a process network, and a logic variable shared between two clauses can be viewed as a communication channel between two processes.
↑  Gert Smolka. . 1998  [2024-03-13]. （原始内容存档于2024-03-13）. As base language we choose a dynamically type language DML that is obtained from SML by eliminating type declarations and static type checking. ……
A state is a finite function σ mapping addresses a to so-called units u. Units are either primitive values other than names or representations of records, variants, reference cells, functions, and primitive operations …… A match Match is a sequence of clauses (p1 ⇒ e1 | … | pk ⇒ ek). ……
We now extend DML with logic variables, one of the essentials of logic programming. Logic variables are a means to represent in a state partial information about the values of addresses. Logic variables are modelled with a new unit lvar. The definition of states is extended so that a state may map an address also to lvar or an address. ……
A match …… blocks until the store contains enough information to commit to one of the clauses or to know that none applies.
1 2  Jan Schwinghammer. . 2002  [2024-03-14]. （原始内容存档于2024-03-14）. General logic variables stem from the class of logic programming languages such as Prolog [Pro85, SS94, JL87]. Initially, when freshly introduced, they carry no value. Therefore they allow for the stepwise construction of values, using further logic variables for the construction of subvalues if necessary. They are transient, in that they are identified with their value as soon as this becomes available. This provides a mechanism for implicit synchronization of concurrent threads that share a logic variable: A thread reading the variable automatically suspends while sufficient information is not available.
We will be concerned with futures and promises, which differ from general logic variables in that a distinction is made between reading and writing them. Bidirectional unification can be replaced by (single-) assignment.
1 2  Rishiyur S. Nikhil.  (PDF). 1991  [2024-03-13]. （原始内容存档 (PDF)于2024-05-19）. A component of a data structure may have I-structure semantics (as opposed to functional or M-structure semantics). For such a component, no value is specified when the data structure is created; instead, a separate assignment statement is used. An I-structure component may be in one of two states: be full (with a value), or empty. all components begin in the empty state (when the data structure is allocated).
An I-structure component has a single assignment restriction, i.e. it can only be assigned once, at which point its state goes from empty to full. Any attempt to assign it more than once is caught as a runtime error. The component can be read an arbitrary number of times.
……
An M-structure component can be assigned with a put operation and read with a take operation. A value can be put only into an empty component — it is a runtime error if it is already full. Many take's may be attempted concurrently on a component.
1 2  .   [2024-03-13]. （原始内容存档于2024-05-10）. The SyncVar structure provides Id-style synchronous variables (or memory cells). These variables have two states: empty and full. An attempt to read a value from an empty variable blocks the calling thread until there is a value available. An attempt to put a value into a variable that is full results in the Put exception being raised. There are two kinds of synchronous variables: I-variables are write-once, while M-variables are mutable.
↑  , Sunless Sea,   [2018-12-31], （原始内容存档于2007-10-23）
↑  
, MIT,   [2018-12-31], （原始内容存档于2018-04-27）
↑  Liskov, Barbara, , Oral history, IEEE GHN,   [2018-12-31], （原始内容存档于2014-11-22）
↑  
, Udanax,   [2018-12-31], （原始内容存档于2008-10-11）
↑  , E rights,   [2018-12-31], （原始内容存档于2018-10-22）
↑  Henry Lieberman. . MIT AI memo 625. June 1981.
↑  Henry Lieberman. . MIT AI memo 626. June 1981.
↑  .   [2024-03-11]. （原始内容存档于2024-03-11）.
1 2  . April 3rd, 2012  [2024-03-20]. （原始内容存档于2024-03-20）.  请检查|date=中的日期值 (帮助)
1 2 3  
. Msdn.microsoft.com.   [2014-05-13]. （原始内容存档于2014-05-27）.
↑  Don Syme; Tomas Petricek; Dmitry Lomov. . 2010-10-21. This paper describes the asynchronous support in F# 2.0. While the core idea was released and published in book form 2007, the model has not been described in the conference literature.
↑  Tomas Petricek. . 2010-10-29  [2018-12-31]. （原始内容存档于2018-12-31）. Currently, you can run the operation on a background thread or using a Task, but coordinating multiple such operations is difficult. …… This problem has been the main motivation for including asynchronous workflows in F# about 3 years ago. In F#, this also enabled various interesting programming styles - for example creating GUI using asynchronous workflows ……. The C# asynchronous programming support and the await keyword is largely inspired by F# asynchronous workflows …….
1 2  Gilad Bracha. . October 2014  [2018-12-31]. （原始内容存档于2016-07-02）.
1 2  .   [2018-12-31]. （原始内容存档于2019-01-05）.
↑  Kenjiro Taura; Satoshi Matsuoka; Akinori Yonezawa. . . American Mathematical Society: 275–292. 1994. CiteSeerX 10.1.1.23.1161 .
1 2 3  .   [2024-03-13]. （原始内容存档于2024-04-17）.
↑  .   [2018-12-31]. （原始内容存档于2016-03-04）.
↑  .   [2018-12-31]. （原始内容存档于2018-12-31）.
↑  .   [2024-03-13]. （原始内容存档于2024-03-13）.
↑  Steve Dekorte. . 2005  [2018-12-31]. （原始内容存档于2019-01-04）.
1 2  .   [2024-03-11]. （原始内容存档于2024-05-21）.
1 2  .   [2024-03-11]. （原始内容存档于2024-04-29）.
↑  . Mozilla Developer Network.   [23 February 2021]. （原始内容存档于2024-05-24）.
↑  . Mozilla Developer Network.   [23 February 2021]. （原始内容存档于2022-03-05）.
↑  Rich Hickey. . 2009  [2018-12-31]. （原始内容存档于2016-02-18）.
↑  .   [2024-01-22]. （原始内容存档于2024-03-06）.
↑  .   [2024-03-11]. （原始内容存档于2024-05-21）.
↑  .   [2024-03-12]. （原始内容存档于2024-03-12）.
↑  Seif Haridi; Nils Franzen. . Mozart Global User Library.   [2011-04-12]. （原始内容存档于2011-05-14）.
1 2  .   [2018-12-31]. （原始内容存档于2018-12-31）.
↑  . Python.org.   [2018-12-31]. （原始内容存档于2018-12-31）.
↑  .   [2018-12-31]. （原始内容存档于2018-12-31）. The proposed design of this module was heavily influenced by the Java java.util.concurrent package [1]. The conceptual basis of the module, as in Java, is the Future class, which represents the progress and result of an asynchronous computation. The Future class makes little commitment to the evaluation mode being used e.g. it can be used to represent lazy or eager evaluation, for evaluation using threads, processes or remote procedure call.
Futures are created by concrete implementations of the Executor class (called ExecutorService in Java). The reference implementation provides classes that use either a process or a thread pool to eagerly evaluate computations.
↑  . Python.org.   [2018-12-31]. （原始内容存档于2019-01-05）.
↑  . raku.org.   [2022-08-19]. （原始内容存档于2024-03-12）.
↑  . doc.rust-lang.org.   [2023-12-16]. （原始内容存档于2024-05-22）.
↑  scala.concurrent包（页面存档备份，存于）
↑  . orthecreedence.github.io.   [2018-12-31]. （原始内容存档于2017-11-10）.
↑  . common-lisp.net.   [2019-01-04]. （原始内容存档于2018-12-31）.
↑  -  Common Lisp的并行编程库[永久]
↑  . marijnhaverbeke.nl.   [2018-12-31]. （原始内容存档于2020-08-06）.
↑  .   [2013-06-26]. （原始内容存档于2019-10-16）.
↑  .   [2013-06-26]. （原始内容存档于2019-10-16）.
↑  . Qt Project.   [2013-06-26]. （原始内容存档于2013-06-01）.
↑  . Seastar project.   [2016-08-22]. （原始内容存档于2016-08-20）.
↑  .   [2018-12-31]. （原始内容存档于2019-03-22）.
↑   (PDF).   [2018-12-31]. （原始内容存档 (PDF)于2020-05-08）.
↑  .   [2018-12-31]. （原始内容存档于2013-01-12）.
1 2  . promisesaplus.com.   [2019-01-04]. （原始内容存档于2018-12-29）.
↑  .   [2018-12-31]. （原始内容存档于2018-12-31）.
↑  . cujojs.com.   [2019-01-04]. （原始内容存档于2012-03-17）.
↑  . 2018-12-25  [2018-12-31]. （原始内容存档于2019-01-16） –GitHub.
↑  . dojotoolkit.org.   [2019-01-04]. （原始内容存档于2018-12-31）.
↑  . MochiKit.Async.   [2019-01-04]. （原始内容存档于2018-12-31）.
↑  .   [2018-12-31]. （原始内容存档于2012-02-29）.
↑  .   [2024-01-26]. （原始内容存档于2012-10-30）.
↑  CommonJS Promises/A（页面存档备份，存于）
↑  . angularjs.org.   [2019-01-04]. （原始内容存档于2015-06-23）.
↑  .   [2024-01-24]. （原始内容存档于2024-05-09）.
↑  . 2019-01-03  [2018-12-31]. （原始内容存档于2019-01-17） –GitHub.
↑  . 2019-01-04  [2018-12-31]. （原始内容存档于2018-12-28） –GitHub.
↑  promise（页面存档备份，存于）
↑  . JDeferred.   [2019-01-04]. （原始内容存档于2019-01-08）.
↑  . 2018-12-29  [2018-12-31]. （原始内容存档于2018-06-10） –GitHub.
↑  . 2019-01-01  [2018-12-31]. （原始内容存档于2019-02-13） –GitHub.
↑  . www.mikeash.com.   [2019-01-04]. （原始内容存档于2018-12-31）.
↑  . 2018-12-26  [2018-12-31]. （原始内容存档于2018-06-11） –GitHub.
↑  . 2018-12-07  [2018-12-31]. （原始内容存档于2018-06-11） –GitHub.
↑  . 2019-01-03  [2019-01-04]. （原始内容存档于2019-01-08） –GitHub.
↑  . 2018-09-11  [2018-12-31]. （原始内容存档于2018-06-11） –GitHub.
↑  . 2017-03-29  [2018-12-31]. （原始内容存档于2013-10-27） –GitHub.
↑  . caml.inria.fr.   [2018-12-31]. （原始内容存档于2015-07-06）.
↑  . metacpan.org.   [2019-01-04]. （原始内容存档于2019-01-01）.
↑  . metacpan.org.   [2018-12-31]. （原始内容存档于2018-12-31）.
↑  . metacpan.org.   [2019-01-04]. （原始内容存档于2019-01-04）.
↑  . 2019-01-04  [2018-12-31]. （原始内容存档于2019-04-07） –GitHub.
↑  .   [2024-01-23]. （原始内容存档于2024-01-23）.
↑  . twistedmatrix.com.   [2024-01-23]. （原始内容存档于2024-04-25）.
1 2  Bengtsson, Henrik. . 2018-10-17  [2018-12-31]. （原始内容存档于2019-10-16） –R-Packages.
↑  . rubygems.org.   [2019-01-04]. （原始内容存档于2018-12-31）.
↑  . 2018-10-16  [2018-12-31]. （原始内容存档于2018-06-11） –GitHub.
↑  . celluloid.io.   [2019-01-04]. （原始内容存档于2018-12-31）.
↑  . 2013-12-27  [2018-12-31]. （原始内容存档于2018-06-11） –GitHub.
↑  . 2019-01-04  [2019-01-04]. （原始内容存档于2019-02-26） –GitHub.
↑  . twitter.github.io.   [2018-12-31]. （原始内容存档于2018-12-23）.
↑  . bitbucket.org.   [2018-12-31]. （原始内容存档于2018-12-31）.
↑  . 2018-12-31  [2018-12-31]. （原始内容存档于2018-08-10） –GitHub.
↑  . developer.apple.com.   [2019-01-04]. （原始内容存档于2018-12-31）.
↑  . 2018-10-15  [2018-12-31]. （原始内容存档于2018-06-12） –GitHub.
↑  . 2019-01-02  [2019-01-04]. （原始内容存档于2018-06-10） –GitHub.
↑  . 2019-01-03  [2018-12-31]. （原始内容存档于2018-06-11） –GitHub.
↑  . SourceForge.   [2018-12-31]. （原始内容存档于2018-12-31）.
↑  .   [2024-03-08]. （原始内容存档于2024-03-08）.
↑  .   [2024-03-11]. （原始内容存档于2019-05-05）.
↑  Kris Zyp. . 2009-05-25  [2024-03-20]. （原始内容存档于2024-03-20）. 
.   [2024-03-20]. （原始内容存档于2024-03-20）.
↑  .   [2024-03-11]. （原始内容存档于2024-05-21）. 
.   [2024-03-25]. （原始内容存档于2024-05-11）. 
.   [2024-03-25]. （原始内容存档于2024-05-09）.
↑  , Site Pen, 2010-05-03  [2018-12-31], （原始内容存档于2018-12-31）
1 2  .   [2024-03-13]. （原始内容存档于2024-04-17）.
↑  500 lines or less, "A Web Crawler With asyncio Coroutines" by A. Jesse Jiryu Davis and Guido van Rossum （页面存档备份，存于） says "implementation uses an asyncio.Event in place of the Future shown here. The difference is an Event can be reset, whereas a Future cannot transition from resolved back to pending."
↑  , Haskell,   [2018-12-31], （原始内容存档于2009-04-18）
↑  , E rights,   [2018-12-31], （原始内容存档于2018-12-31）
↑  . www.erights.org.   [2018-12-31]. （原始内容存档于2018-10-22）.
↑  .   [2018-12-31]. （原始内容存档于2005-09-25）.
↑  , Mozart Oz,   [2018-12-31], （原始内容存档于2013-05-17）