1
Fork 0
mirror of https://git.savannah.gnu.org/git/guile.git synced 2025-05-20 11:40:18 +02:00

Revert "SRFI-45: Support multiple values; add promise? predicate."

This reverts commit 1d64b4edb9.
This commit is contained in:
Mark H Weaver 2013-03-26 21:16:26 -04:00
parent 59b0f9d763
commit 65ad02b96d
3 changed files with 32 additions and 89 deletions

View file

@ -3845,58 +3845,45 @@ 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 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).
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.
@end deffn
@deffn {Scheme Syntax} lazy expression
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.
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.
@end deffn
@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.
@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.
@end deffn
@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
@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
@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. For expressions that
return a single value, we also have the equivalence
unnecessary creation and evaluation of thunks. 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
@ -3906,7 +3893,7 @@ usage semantics specified above:
@lisp
(force (delay expression)) -> expression
(force (lazy expression)) -> (force expression)
(force (eager obj ...)) -> (values obj ...)
(force (eager value)) -> value
@end lisp
@subsubheading Correct usage

View file

@ -1,6 +1,6 @@
;;; srfi-45.scm -- Primitives for Expressing Iterative Lazy Algorithms
;; Copyright (C) 2010, 2011, 2013 Free Software Foundation, Inc.
;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
;; Copyright (C) 2003 André van Tonder. All Rights Reserved.
;; Permission is hereby granted, free of charge, to any person
@ -25,8 +25,8 @@
;;; Commentary:
;; This is the code of the reference implementation of SRFI-45,
;; modified to use SRFI-9 and to support multiple values.
;; This is the code of the reference implementation of SRFI-45, slightly
;; modified to use SRFI-9.
;; This module is documented in the Guile Reference Manual.
@ -36,9 +36,8 @@
#:export (delay
lazy
force
eager
promise?)
#:replace (delay force promise?)
eager)
#:replace (delay force)
#:use-module (srfi srfi-9))
(cond-expand-provide (current-module) '(srfi-45))
@ -53,18 +52,16 @@
(define-syntax-rule (lazy exp)
(make-promise (make-value 'lazy (lambda () exp))))
(define (eager . xs)
(make-promise (make-value 'eager xs)))
(define (eager x)
(make-promise (make-value 'eager x)))
(define-syntax-rule (delay exp)
(lazy (call-with-values
(lambda () exp)
eager)))
(lazy (eager exp)))
(define (force promise)
(let ((content (promise-val promise)))
(case (value-tag content)
((eager) (apply values (value-proc content)))
((eager) (value-proc content))
((lazy) (let* ((promise* ((value-proc content)))
(content (promise-val promise))) ; *
(if (not (eqv? (value-tag content) 'eager)) ; *

View file

@ -1,7 +1,6 @@
;;; -*- mode: scheme; coding: utf-8; -*-
;; Copyright (C) 2010, 2013 Free Software Foundation, Inc.
;; Copyright (C) 2003 André van Tonder. All Rights Reserved.
;; Copyright André van Tonder. All Rights Reserved.
;;
;; Permission is hereby granted, free of charge, to any person
;; obtaining a copy of this software and associated documentation
@ -259,43 +258,3 @@
;; Commented out since it takes too long
#;
(test-equal 300000000 (force (times3 100000000))) ;==> bounded space
;======================================================================
; Test promise? predicate (non-standard Guile extension)
(pass-if "promise? predicate"
(promise? (delay 1)))
;======================================================================
; Test memoization of multiple values (non-standard Guile extension)
(with-test-prefix "Multiple values (non-standard)"
(let ((promise (delay (values 1 2 3))))
(pass-if-equal "Multiple values delay"
'(1 2 3)
(call-with-values
(lambda () (force promise))
list)))
(let ((promise (eager 1 2 3)))
(pass-if-equal "Multiple values eager"
'(1 2 3)
(call-with-values
(lambda () (force promise))
list)))
(let ((promise (delay (values))))
(pass-if-equal "Zero values delay"
'()
(call-with-values
(lambda () (force promise))
list)))
(let ((promise (eager)))
(pass-if-equal "Zero values eager"
'()
(call-with-values
(lambda () (force promise))
list))))