mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-06-21 03:00:19 +02:00
SRFI-45: Support multiple values; add promise? predicate.
* module/srfi/srfi-45.scm (eager): Accept any number of arguments. Store the list of arguments in the value record. Previously, only one argument was accepted, and that value was stored in the value record. (delay): Support expressions that return any number of arguments. (force): Return the list of values stored in the value record. (promise?): Export. * doc/ref/srfi-modules.texi (SRFI-45): Update docs. Remove typing for simplicity in discussing multiple values. * test-suite/tests/srfi-45.test: Add tests. Add FSF copyright for 2010 and 2013. Add missing year to André van Tonder's copyright notice.
This commit is contained in:
parent
8150dfa1f2
commit
1d64b4edb9
3 changed files with 89 additions and 32 deletions
|
@ -3833,45 +3833,58 @@ words, no program that uses the R5RS definitions of delay and force will
|
|||
break if those definition are replaced by the SRFI-45 definitions of
|
||||
delay and force.
|
||||
|
||||
Guile compatibly extends SRFI-45 to support multiple values. It also
|
||||
adds @code{promise?} to the list of exports.
|
||||
|
||||
@deffn {Scheme Procedure} promise? obj
|
||||
Return true if @var{obj} is an SRFI-45 promise, otherwise return false.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Syntax} delay expression
|
||||
Takes an expression of arbitrary type @var{a} and returns a promise of
|
||||
type @code{(Promise @var{a})} which at some point in the future may be
|
||||
asked (by the @code{force} procedure) to evaluate the expression and
|
||||
deliver the resulting value.
|
||||
Takes an expression and returns a promise which at some point in the
|
||||
future may be asked (by the @code{force} procedure) to evaluate the
|
||||
expression and deliver the resulting value(s).
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Syntax} lazy expression
|
||||
Takes an expression of type @code{(Promise @var{a})} and returns a
|
||||
promise of type @code{(Promise @var{a})} which at some point in the
|
||||
future may be asked (by the @code{force} procedure) to evaluate the
|
||||
expression and deliver the resulting promise.
|
||||
Takes an expression (which must evaluate to a promise) and returns a
|
||||
promise which at some point in the future may be asked (by the
|
||||
@code{force} procedure) to evaluate the expression and deliver the
|
||||
resulting promise.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} force expression
|
||||
Takes an argument of type @code{(Promise @var{a})} and returns a value
|
||||
of type @var{a} as follows: If a value of type @var{a} has been computed
|
||||
for the promise, this value is returned. Otherwise, the promise is
|
||||
first evaluated, then overwritten by the obtained promise or value, and
|
||||
then force is again applied (iteratively) to the promise.
|
||||
@deffn {Scheme Procedure} force promise
|
||||
Takes a promise and returns the associated value(s) as follows: If
|
||||
value(s) have been computed for the promise, these value(s) are
|
||||
returned. Otherwise, the promise is first evaluated, then overwritten
|
||||
by the obtained promise or value(s), and then force is again applied
|
||||
(iteratively) to the promise.
|
||||
@end deffn
|
||||
|
||||
@deffn {Scheme Procedure} eager expression
|
||||
Takes an argument of type @var{a} and returns a value of type
|
||||
@code{(Promise @var{a})}. As opposed to @code{delay}, the argument is
|
||||
evaluated eagerly. Semantically, writing @code{(eager expression)} is
|
||||
equivalent to writing
|
||||
@deffn {Scheme Procedure} eager obj ...
|
||||
Takes any number of argument(s) and returns a promise. As opposed to
|
||||
@code{delay}, the argument(s) are evaluated eagerly. Semantically,
|
||||
writing @code{(eager expression)} is equivalent to writing
|
||||
|
||||
@lisp
|
||||
(let ((value expression)) (delay value)).
|
||||
@end lisp
|
||||
|
||||
However, the former is more efficient since it does not require
|
||||
unnecessary creation and evaluation of thunks. We also have the
|
||||
equivalence
|
||||
unnecessary creation and evaluation of thunks. For expressions that
|
||||
return a single value, we also have the equivalence
|
||||
|
||||
@lisp
|
||||
(delay expression) = (lazy (eager expression))
|
||||
@end lisp
|
||||
|
||||
More generally, the following equivalence holds:
|
||||
|
||||
@lisp
|
||||
(delay expression) = (lazy (call-with-values
|
||||
(lambda () expression)
|
||||
eager))
|
||||
@end lisp
|
||||
@end deffn
|
||||
|
||||
The following reduction rules may be helpful for reasoning about these
|
||||
|
@ -3881,7 +3894,7 @@ usage semantics specified above:
|
|||
@lisp
|
||||
(force (delay expression)) -> expression
|
||||
(force (lazy expression)) -> (force expression)
|
||||
(force (eager value)) -> value
|
||||
(force (eager obj ...)) -> (values obj ...)
|
||||
@end lisp
|
||||
|
||||
@subsubheading Correct usage
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue