9.3 Delayed Evaluation
A promise encapsulates an expression to be evaluated on
demand via force. After a promise has been forced,
every later force of the promise produces the same result.
This module provides this functionality, and extends it to additional
kinds of promises with various evaluation strategies.
Returns #t if v is a promise, #f
Creates a promise that, when force
d, evaluates the
s to produce its value. The result is then cached, so
further uses of force
produce the cached value immediately.
This includes multiple values and exceptions.
, if the last body
produces a promise when
forced, then this promise is force
d too to obtain a value.
In other words, this form creates a composable promise, where the
computation of its body is “attached” to the computation of the
following promise and a single force
iterates through the
whole chain, tail-calling each step.
Note that the last body of this form must produce a single
value – but this value can itself be a delay promise that
returns multiple values.
This form useful for implementing lazy libraries and languages, where
tail-calls can be wrapped in a promise.
is a promise, then the promise is forced to obtain a
value. If the promise has not been forced before, then the result is
recorded in the promise so that future force
s on the promise
produce the same value (or values). If forcing the promise raises an
exception, then the exception is similarly recorded so that forcing
the promise will raise the same exception every time.
If v is forced again before the original call to
force returns, then the exn:fail exception is raised.
Additional kinds of promises are also forced via force. See
below for further details.
If v is not a promise, then it is returned as the result.
Returns #t if promise has been forced.
Returns #t if promise is currently being forced.
(Note that a promise can be either running or forced but not both.)
9.3.1 Additional Promise Kinds
Creates a “call by name” promise, that is similar to
-promises, except that the resulting value is not
cached. It is essentially a thunk, wrapped in a way that
recognizes. Note that if a delay/name
forces itself, no exception is raised.
Note that this promise is never considered “running” or “forced”
in the sense of promise-running? and
Conventional promises are not useful when multiple threads attempt to
force them: when a promise is running, any additional threads that
it will get an exception. delay/sync
useful for such cases: if a second thread attempts to force
such a promise, it will get blocked until the computation is done and
an answer is available. If force
is used with the promise as
it is forced from the same thread, an exception is raised.
In addition, these promises can be used with sync, which
blocks until it has been forced. Note that using sync this
way is passive in the sense that it does not trigger evaluation of the
This kind of promise begins the computation immediately, but this
happens on a separate thread. When the computation is done, the result
is cached as usual. Note that exceptions are caught as usual, and will
only be raised when force
d. If such a promise is
d before a value is ready, the calling thread will be
blocked until the computation terminates. These promises can also be
used with sync
Similar to delay/thread
, but the computation thread gets to
work only when the process is otherwise idle, as determined by
, and the work is done in small runtime
fragements, making it overall not raise total CPU use or hurt
responsiveness. If the promise is forced
computation is done, it will run the rest of the computation immediately
without slicing the runtime. Using sync
on these promises
blocks as is the case with delay/sync
, and this happens in a
passive way too, so the computation continues to work in low-priority.