12 Promises

A promise is an object that represents the potential to determine a value. The value may be the result of an arbitrary computation that will not be performed until the value must be determined (constructor $lazy); or, in advanced usage, the value may be determined before the promise is constructed (constructor memoize).

The value determined by a promise is obtained by forcing it (applicative force). A given promise cannot determine different values on different occasions that it is forced. Also, if a promise determines its value by computation, and that computation has already been completed, forcing the promise again will produce the previously determined result without re-initiating the computation to determine it.

The Kernel data type promise is encapsulated.

The general rules for predicate eq? only require it to distinguish promises if they can exhibit different behavior; the resulting leeway for variation between implementations is similar, in both cause and effect, to that for eq?-ness of operatives. For example, if two promises, constructed on different occasions, would perform the same computation to determine their values, and that computation has no side-effects and must always return the same value, the promises may or may not be eq?. Two promises are equal? iff they are eq?.

— Applicative: promise? (promise? . objects)

The primitive type predicate for type promise. promise? returns true iff all the objects in objects are of type promise.

— Applicative: force (force object)

If object is a promise, applicative force returns the value determined by promise; otherwise, it returns object.

The means used to force a promise depend on how the promise was constructed. The description of each promise constructor specifies how to force promises constructed by that constructor.

— Operative: $lazy ($lazy expression)

Operative $lazy constructs and returns a new object of type promise, representing potential evaluation of expression in the dynamic environment from which $lazy was called.

When the promise is forced, if a value has not previously been determined for it, expression is evaluated in the dynamic environment of the constructing call to $lazy. If, when the evaluation returns a result, a value is found to have been determined for the promise during the evaluation, the result is discarded in favor of the previously determined value; otherwise, the result is forced, and the value returned by that forcing becomes the value determined by the promise.

Forcing an undetermined lazy promise (i.e., a promise constructed by $lazy for which no value has yet been determined) may cause a sequential series of evaluations, each of which returns a promise that is forced and thus initiates the next evaluation in the series. The implementation must support series of this kind with unbounded length (i.e., unbounded number of sequential evaluations).

Note that forcing concerns the value determined by a given promise, not the result of evaluating a given expression in a given environment. Distinct promises (judged by eq? represent different occasions of evaluation; so, even if they do represent evaluation of the same expression in the same environment, forcing one does not necessarily determine the value for the other, and actual evaluation will take place the first time each of them is forced.

— Applicative: memoize (memoize object)

Applicative memoize constructs and returns a new object of type promise, representing memoization of object. Whenever the promise is forced, it determines object.

— Operative: $delay ($delay <expression>)

Operative delay behaves as the composition of $lazy and memoize, that is:

          ($delay <expr>) == ($lazy (memoize <expr>))

SOURCE NOTE: this is taken from r7rs.