10.3 Delayed Evaluation
(require racket/promise) | package: base |
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.
syntax
(delay body ...+)
syntax
(lazy body ...+)
Note that the last body of this form must produce a single value, but the value can itself be a delay promise that returns multiple values.
The lazy form is useful for implementing lazy libraries and languages, where tail calls can be wrapped in a promise.
If v is forced again before the original call to force returns, then the exn:fail exception is raised.
If v is not a promise, then it is returned as the result.
procedure
(promise-forced? promise) → boolean?
promise : promise?
procedure
(promise-running? promise) → boolean?
promise : promise?
10.3.1 Additional Promise Kinds
syntax
(delay/name body ...+)
If a delay/name promise forces itself, no exception is raised, the promise is never considered “running” or “forced” in the sense of promise-running? and promise-forced?.
procedure
(promise/name? promise) → boolean?
promise : any/c
Added in version 6.3 of package base.
syntax
(delay/strict body ...+)
syntax
(delay/sync body ...+)
If a promise created by delay/sync is forced on a thread that is already running the promise, an exception is raised in the same way as for promises created with delay.
syntax
(delay/thread body/option ...+)
body/option = body | #:group thread-group-expr
Exceptions raised by the bodys are caught as usual and raised only when the promise is forced. Unlike delay/sync, if the thread running body terminates without producing a result or exception, force of the promise raises an exception (instead of blocking).
syntax
(delay/idle body/option ...+)
body/option = body | #:wait-for wait-evt-expr | #:work-while while-evt-expr | #:tick tick-secs-expr | #:use use-ratio-expr
the computation does not start until the event produced by wait-evt-expr is ready, where the default is (system-idle-evt);
the computation thread gets to work only when the process is otherwise idle as determined by while-evt-expr, which also defaults to (system-idle-evt);
the thread is allowed to run only periodically: out of every tick-secs-expr (defaults to 0.2) seconds, the thread is allowed to run use-ratio-expr (defaults to 0.12) of the time proportionally; i.e., the thread runs for (* tick-secs-expr use-ratio-expr) seconds.
If the promise is forced before the computation is done, it runs the rest of the computation immediately without waiting on events or periodically restricting evaluation.
A #:wait-for, #:work-while, #:tick, or #:use specification can appear at most once.
syntax
(for/list/concurrent maybe-group (for-clause ...) body-or-break ... body)
maybe-group =
| #:group thread-group-expr
thread-group-expr : thread-group?
Threads are created under thread-group-expr, which defaults to (make-thread-group). An optional #:group clause may be provided, in which case the threads will be created under that thread group.
This form does not support returning multiple values.
> (time (for/list/concurrent ([i (in-range 5)]) (define duration (/ 1.0 (random 50 100))) (sleep duration) (printf "thread ~a slept for ~a milliseconds~n" i (truncate (* duration 1000))) i))
thread 3 slept for 10.0 milliseconds
thread 0 slept for 10.0 milliseconds
thread 4 slept for 11.0 milliseconds
thread 1 slept for 11.0 milliseconds
thread 2 slept for 15.0 milliseconds
cpu time: 2 real time: 15 gc time: 0
'(0 1 2 3 4)
Added in version 8.6.0.4 of package base.
syntax
(for*/list/concurrent maybe-group (for-clause ...) body-or-break ... body)
Added in version 8.6.0.4 of package base.