► |  | Reference: PLT Scheme

1 | Language Model
2 | Syntactic Forms
3 | Datatypes
4 | Structures
5 | Classes and Objects
6 | Units
7 | Contracts
8 | Pattern Matching
9 | Control Flow
10 | Concurrency
11 | Macros
12 | Input and Output
13 | Reflection and Security
14 | Operating System
15 | Memory Management
16 | Unsafe Operations
17 | Running PLT Scheme
| Bibliography
| Index

▼ | 9 | Control Flow

9.1 | Multiple Values
9.2 | Exceptions
9.3 | Delayed Evaluation
9.4 | Continuations
9.5 | Continuation Marks
9.6 | Breaks
9.7 | Exiting

► | 9.3 | Delayed Evaluation

9.3.1 | Additional Promise Kinds

On this page:

promise?
delay
lazy
force
promise-forced?
promise-running?
9.3.1`` Additional Promise Kinds
delay/ name
delay/ sync
delay/ thread
delay/ idle

top← prev up next →

#### 9.3`` Delayed Evaluation

(require scheme/promise)

The bindings documented in this section are provided by the scheme/promise and scheme libraries, but not scheme/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.

This module provides this functionality, and extends it to additional kinds of promises with various evaluation strategies.

(promise? v) → boolean?
v : any/c

Returns #t if v is a promise, #f otherwise.

(delay body ...+)

Creates a promise that, when forced, evaluates the bodys 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.

(lazy body ...+)

Like delay, if the last body produces a promise when forced, then this promise is forced 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.

(force v) → any
v : any/c

If v 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 forces 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.

(promise-forced? promise) → boolean?
promise : promise?

Returns #t if promise has been forced.

(promise-running? promise) → boolean?
promise : promise?

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

(delay/name body ...+)

Creates a “call by name” promise, that is similar to delay-promises, except that the resulting value is not cached. It is essentially a thunk, wrapped in a way that force recognizes. Note that if a delay/name promise forces itself, no exception is raised.

Note that this promise is never considered “running” or “forced” in the sense of promise-running? and promise-forced?.

(delay/sync body ...+)

Conventional promises are not useful when multiple threads attempt to force them: when a promise is running, any additional threads that force it will get an exception. delay/sync is 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 promise.

(delay/thread body ...+)

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 forced. If such a promise is forced before a value is ready, the calling thread will be blocked until the computation terminates. These promises can also be used with sync.

(delay/idle body ...+)

Similar to delay/thread, but the computation thread gets to work only when the process is otherwise idle, as determined by system-idle-evt, 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 before the 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.
top← prev up next →