control.future
- Futures ¶A future is a simple construct for concurrent computation.
It encloses an expression, and compute its value concurrently. The result
of computation can be retrieved later with future-get
.
Futures are introduced in MultiLisp, in which retrieval of the computed
value is implicit—a future is substituted with the result automatically.
Racket and Guile have futures as a library, though the primitive to
retrieve the result is called touch
. We avoided to use the name
since touch
is too generic.
{control.future
}
Returns a future object, which runs the computation of expr in
a separate thread. The result(s) of expr can be retrieved by
future-get
. Note that expr can yield multiple values.
The expr is evaluated in the same environment
as future
appears, though if an exception raised within expr
is not caught, its delivery is delayed until you call future-get
.
The following example runs HTTP access concurrently with other computation, and retrieves the result later.
(use control.future) (use rfc.http) (let1 f (future (http-get "example.com" "/")) ... some computation ... (receive (code headers body) (future-get f) ...))
{control.future
}
Returns a future that calls thunk in a separate thread.
(future expr) ≡ (make-future (lambda () expr))
{control.future
}
Returns #t
if obj is a future, #f
otherwise.
{control.future
}
The argument must be a future. Retrieve the result(s) of future.
If the result of future is already available, it is returned immediately.
If future is still computing, future-get
blocks until
the result is ready by default. You can limit how long you will wait by
timeout argument, which can be #f
(default, no timeout),
a nonnegative real numebr (relative time in seconds), or
a <time>
object (absolute timepoint). If the timeout reaches
before the result is available, timeout-val is returned, which
defaults to #f
.
Calling future-get
more than once returns the same result.
If an uncaught exception is raised during computation in the future,
it is kept and reraised from future-get
. It is handled
in the dynamic environment of future-get
(not the one in the original
future
call).
If you call future-get
again on such future, the effect is undefined
(currently it returns #<undef>
without raising an exception, but
it may change in future).
{control.future
}
Returns #t
if computation in future is finished,
#f
otherwise.