mirror of
https://git.savannah.gnu.org/git/guile.git
synced 2025-05-20 19:50:24 +02:00
Revert "SRFI-45: Support multiple values; add promise? predicate."
This reverts commit 1d64b4edb9
.
This commit is contained in:
parent
59b0f9d763
commit
65ad02b96d
3 changed files with 32 additions and 89 deletions
|
@ -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
|
break if those definition are replaced by the SRFI-45 definitions of
|
||||||
delay and force.
|
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
|
@deffn {Scheme Syntax} delay expression
|
||||||
Takes an expression and returns a promise which at some point in the
|
Takes an expression of arbitrary type @var{a} and returns a promise of
|
||||||
future may be asked (by the @code{force} procedure) to evaluate the
|
type @code{(Promise @var{a})} which at some point in the future may be
|
||||||
expression and deliver the resulting value(s).
|
asked (by the @code{force} procedure) to evaluate the expression and
|
||||||
|
deliver the resulting value.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Syntax} lazy expression
|
@deffn {Scheme Syntax} lazy expression
|
||||||
Takes an expression (which must evaluate to a promise) and returns a
|
Takes an expression of type @code{(Promise @var{a})} and returns a
|
||||||
promise which at some point in the future may be asked (by the
|
promise of type @code{(Promise @var{a})} which at some point in the
|
||||||
@code{force} procedure) to evaluate the expression and deliver the
|
future may be asked (by the @code{force} procedure) to evaluate the
|
||||||
resulting promise.
|
expression and deliver the resulting promise.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} force promise
|
@deffn {Scheme Procedure} force expression
|
||||||
Takes a promise and returns the associated value(s) as follows: If
|
Takes an argument of type @code{(Promise @var{a})} and returns a value
|
||||||
value(s) have been computed for the promise, these value(s) are
|
of type @var{a} as follows: If a value of type @var{a} has been computed
|
||||||
returned. Otherwise, the promise is first evaluated, then overwritten
|
for the promise, this value is returned. Otherwise, the promise is
|
||||||
by the obtained promise or value(s), and then force is again applied
|
first evaluated, then overwritten by the obtained promise or value, and
|
||||||
(iteratively) to the promise.
|
then force is again applied (iteratively) to the promise.
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
@deffn {Scheme Procedure} eager obj ...
|
@deffn {Scheme Procedure} eager expression
|
||||||
Takes any number of argument(s) and returns a promise. As opposed to
|
Takes an argument of type @var{a} and returns a value of type
|
||||||
@code{delay}, the argument(s) are evaluated eagerly. Semantically,
|
@code{(Promise @var{a})}. As opposed to @code{delay}, the argument is
|
||||||
writing @code{(eager expression)} is equivalent to writing
|
evaluated eagerly. Semantically, writing @code{(eager expression)} is
|
||||||
|
equivalent to writing
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
(let ((value expression)) (delay value)).
|
(let ((value expression)) (delay value)).
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
However, the former is more efficient since it does not require
|
However, the former is more efficient since it does not require
|
||||||
unnecessary creation and evaluation of thunks. For expressions that
|
unnecessary creation and evaluation of thunks. We also have the
|
||||||
return a single value, we also have the equivalence
|
equivalence
|
||||||
|
|
||||||
@lisp
|
@lisp
|
||||||
(delay expression) = (lazy (eager expression))
|
(delay expression) = (lazy (eager expression))
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
More generally, the following equivalence holds:
|
|
||||||
|
|
||||||
@lisp
|
|
||||||
(delay expression) = (lazy (call-with-values
|
|
||||||
(lambda () expression)
|
|
||||||
eager))
|
|
||||||
@end lisp
|
|
||||||
@end deffn
|
@end deffn
|
||||||
|
|
||||||
The following reduction rules may be helpful for reasoning about these
|
The following reduction rules may be helpful for reasoning about these
|
||||||
|
@ -3906,7 +3893,7 @@ usage semantics specified above:
|
||||||
@lisp
|
@lisp
|
||||||
(force (delay expression)) -> expression
|
(force (delay expression)) -> expression
|
||||||
(force (lazy expression)) -> (force expression)
|
(force (lazy expression)) -> (force expression)
|
||||||
(force (eager obj ...)) -> (values obj ...)
|
(force (eager value)) -> value
|
||||||
@end lisp
|
@end lisp
|
||||||
|
|
||||||
@subsubheading Correct usage
|
@subsubheading Correct usage
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
;;; srfi-45.scm -- Primitives for Expressing Iterative Lazy Algorithms
|
;;; 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.
|
;; Copyright (C) 2003 André van Tonder. All Rights Reserved.
|
||||||
|
|
||||||
;; Permission is hereby granted, free of charge, to any person
|
;; Permission is hereby granted, free of charge, to any person
|
||||||
|
@ -25,8 +25,8 @@
|
||||||
|
|
||||||
;;; Commentary:
|
;;; Commentary:
|
||||||
|
|
||||||
;; This is the code of the reference implementation of SRFI-45,
|
;; This is the code of the reference implementation of SRFI-45, slightly
|
||||||
;; modified to use SRFI-9 and to support multiple values.
|
;; modified to use SRFI-9.
|
||||||
|
|
||||||
;; This module is documented in the Guile Reference Manual.
|
;; This module is documented in the Guile Reference Manual.
|
||||||
|
|
||||||
|
@ -36,9 +36,8 @@
|
||||||
#:export (delay
|
#:export (delay
|
||||||
lazy
|
lazy
|
||||||
force
|
force
|
||||||
eager
|
eager)
|
||||||
promise?)
|
#:replace (delay force)
|
||||||
#:replace (delay force promise?)
|
|
||||||
#:use-module (srfi srfi-9))
|
#:use-module (srfi srfi-9))
|
||||||
|
|
||||||
(cond-expand-provide (current-module) '(srfi-45))
|
(cond-expand-provide (current-module) '(srfi-45))
|
||||||
|
@ -53,18 +52,16 @@
|
||||||
(define-syntax-rule (lazy exp)
|
(define-syntax-rule (lazy exp)
|
||||||
(make-promise (make-value 'lazy (lambda () exp))))
|
(make-promise (make-value 'lazy (lambda () exp))))
|
||||||
|
|
||||||
(define (eager . xs)
|
(define (eager x)
|
||||||
(make-promise (make-value 'eager xs)))
|
(make-promise (make-value 'eager x)))
|
||||||
|
|
||||||
(define-syntax-rule (delay exp)
|
(define-syntax-rule (delay exp)
|
||||||
(lazy (call-with-values
|
(lazy (eager exp)))
|
||||||
(lambda () exp)
|
|
||||||
eager)))
|
|
||||||
|
|
||||||
(define (force promise)
|
(define (force promise)
|
||||||
(let ((content (promise-val promise)))
|
(let ((content (promise-val promise)))
|
||||||
(case (value-tag content)
|
(case (value-tag content)
|
||||||
((eager) (apply values (value-proc content)))
|
((eager) (value-proc content))
|
||||||
((lazy) (let* ((promise* ((value-proc content)))
|
((lazy) (let* ((promise* ((value-proc content)))
|
||||||
(content (promise-val promise))) ; *
|
(content (promise-val promise))) ; *
|
||||||
(if (not (eqv? (value-tag content) 'eager)) ; *
|
(if (not (eqv? (value-tag content) 'eager)) ; *
|
||||||
|
|
|
@ -1,7 +1,6 @@
|
||||||
;;; -*- mode: scheme; coding: utf-8; -*-
|
;;; -*- mode: scheme; coding: utf-8; -*-
|
||||||
|
|
||||||
;; Copyright (C) 2010, 2013 Free Software Foundation, Inc.
|
;; Copyright André van Tonder. All Rights Reserved.
|
||||||
;; Copyright (C) 2003 André van Tonder. All Rights Reserved.
|
|
||||||
;;
|
;;
|
||||||
;; Permission is hereby granted, free of charge, to any person
|
;; Permission is hereby granted, free of charge, to any person
|
||||||
;; obtaining a copy of this software and associated documentation
|
;; obtaining a copy of this software and associated documentation
|
||||||
|
@ -259,43 +258,3 @@
|
||||||
;; Commented out since it takes too long
|
;; Commented out since it takes too long
|
||||||
#;
|
#;
|
||||||
(test-equal 300000000 (force (times3 100000000))) ;==> bounded space
|
(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))))
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue