LazyEvaluation.mesa
Copyright Ó 1992 by Xerox Corporation. All rights reserved.
Created by Christian Jacobi, March 11, 1992
Christian Jacobi, May 27, 1992 11:18 am PDT
A generic lazy evaluation mechanism.
The active evaluation procedure is called at most once.
LazyEvaluation looks pretty simple; the value of this package lies more in the type code with the implied meaning, and, in the locking scheme then in its mainline functionality.
LazyEvaluation: CEDAR DEFINITIONS ~
BEGIN
Handle: TYPE ~ REF HandleRec;
HandleRec:
TYPE ~
PRIVATE
RECORD [
evaluate: PROC [REF] RETURNS [REF],
data: REF ¬ NIL
];
Once a HandleRec is created the fields must not be accessed, modifed, or, called. (LazyEvaluationImpl might change the values asynchronously.)
Failed:
ERROR;
Raised if an attempt is made to return a result of "UNWIND". (The original evaluation caused an UNWIND, and, "Evaluate" is called again.)
New:
PROC [evaluate:
PROC [
REF]
RETURNS [
REF], data:
REF ¬
NIL]
RETURNS [Handle];
Creates a lazy evaluation handle.
To later evaluate, "evaluate" will be called. "data" is handed to "evaluate".
Evaluate:
PROC [h: Handle]
RETURNS [result:
REF];
Returns the previously evaluated result, or, starts evaluation if none is available and evaluation isn't already in progress. Does all the proper locking to prevent multiple calls.
May raise all errors raised by an actual evaluation, and, also "Failed".
SetResult:
PROC [h: Handle, result:
REF];
Changes result of handle immediately. Prevents starting any active evaluation.
An unmonitored race condition exist if an active evaluation is already on its way when SetResult is called. (This race condition is SAFE; all it means is that it is unspecified which SetResult is executed first)
END.