unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* [PATCH] SRFI-45: Support delayed expressions that return multiple values
@ 2013-03-19  0:30 Mark H Weaver
  2013-03-19  1:08 ` Ian Price
                   ` (2 more replies)
  0 siblings, 3 replies; 9+ messages in thread
From: Mark H Weaver @ 2013-03-19  0:30 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 1463 bytes --]

Hello all,

It turns out that Guile's built-in 'delay' and 'force' support multiple
values properly, but the ones from SRFI-45 do not.

--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> (define promise (delay (values 1 2)))
scheme@(guile-user)> (force promise)
$1 = 1
$2 = 2
scheme@(guile-user)> ,use (srfi srfi-45)
scheme@(guile-user)> (define promise (delay (values 1 2)))
scheme@(guile-user)> (force promise)
$3 = 1
--8<---------------cut here---------------end--------------->8---

Here's a small patch to fix that.  More specifically, it extends 'eager'
to accept any number of arguments, so it can be used just like 'values'.
(That's the only way to do it without making 'eager' a macro).

It changes the expansion of the 'delay' macro, but in a
backward-compatible way: existing compiled code that was expanded from
the old version of the SRFI-45 'delay' macro will continue to work, but
will only keep the first value.  Freshly compiled code will support
multiple values.

--8<---------------cut here---------------start------------->8---
scheme@(guile-user)> ,use (srfi srfi-45)
scheme@(guile-user)> (define promise (delay (values 1 2)))
scheme@(guile-user)> (force promise)
$1 = 1
$2 = 2
scheme@(guile-user)> (define promise (eager 1 2))
scheme@(guile-user)> (force promise)
$3 = 1
$4 = 2
--8<---------------cut here---------------end--------------->8---

Any objections to pushing this to stable-2.0?

      Mark



[-- Attachment #2: [PATCH] SRFI-45: Support delayed expressions that return multiple values --]
[-- Type: text/x-diff, Size: 1990 bytes --]

From bbaca34ea0158ad84e692d631ee8efc85a18b81e Mon Sep 17 00:00:00 2001
From: Mark H Weaver <mhw@netris.org>
Date: Mon, 18 Mar 2013 20:01:12 -0400
Subject: [PATCH] SRFI-45: Support delayed expressions that return multiple
 values.

* 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.
---
 module/srfi/srfi-45.scm |   12 +++++++-----
 1 file changed, 7 insertions(+), 5 deletions(-)

diff --git a/module/srfi/srfi-45.scm b/module/srfi/srfi-45.scm
index 29b0393..3342557 100644
--- a/module/srfi/srfi-45.scm
+++ b/module/srfi/srfi-45.scm
@@ -1,6 +1,6 @@
 ;;; srfi-45.scm -- Primitives for Expressing Iterative Lazy Algorithms
 
-;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+;; Copyright (C) 2010, 2011, 2013 Free Software Foundation, Inc.
 ;; Copyright (C) 2003 André van Tonder. All Rights Reserved.
 
 ;; Permission is hereby granted, free of charge, to any person
@@ -50,16 +50,18 @@
 (define-syntax-rule (lazy exp)
   (make-promise (make-value 'lazy (lambda () exp))))
 
-(define (eager x)
-  (make-promise (make-value 'eager x)))
+(define (eager . xs)
+  (make-promise (make-value 'eager xs)))
 
 (define-syntax-rule (delay exp)
-  (lazy (eager exp)))
+  (lazy (call-with-values
+            (lambda () exp)
+          eager)))
 
 (define (force promise)
   (let ((content (promise-val promise)))
     (case (value-tag content)
-      ((eager) (value-proc content))
+      ((eager) (apply values (value-proc content)))
       ((lazy)  (let* ((promise* ((value-proc content)))
                       (content  (promise-val promise)))        ; *
                  (if (not (eqv? (value-tag content) 'eager))   ; *
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] SRFI-45: Support delayed expressions that return multiple values
  2013-03-19  0:30 [PATCH] SRFI-45: Support delayed expressions that return multiple values Mark H Weaver
@ 2013-03-19  1:08 ` Ian Price
  2013-03-19 18:24   ` Mark H Weaver
  2013-03-19  1:53 ` Mark H Weaver
  2013-03-26 10:32 ` [PATCH] SRFI-45: Support delayed expressions that return multiple values Mark H Weaver
  2 siblings, 1 reply; 9+ messages in thread
From: Ian Price @ 2013-03-19  1:08 UTC (permalink / raw)
  To: Mark H Weaver; +Cc: guile-devel

Mark H Weaver <mhw@netris.org> writes:

> Any objections to pushing this to stable-2.0?

Change is simple enough, and it matches the behaviour of built-in
force/delay. Should be a rubber stamp IMO :)

I note Eli Barzilay contributed some changes in the post-finalisation
archive for srfi 45 to support multiple values.

-- 
Ian Price -- shift-reset.com

"Programming is like pinball. The reward for doing it well is
the opportunity to do it again" - from "The Wizardy Compiled"



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] SRFI-45: Support delayed expressions that return multiple values
  2013-03-19  0:30 [PATCH] SRFI-45: Support delayed expressions that return multiple values Mark H Weaver
  2013-03-19  1:08 ` Ian Price
@ 2013-03-19  1:53 ` Mark H Weaver
  2013-03-19  3:49   ` [PATCH] SRFI-45: Support multiple values; add promise? predicate Mark H Weaver
  2013-03-26 10:32 ` [PATCH] SRFI-45: Support delayed expressions that return multiple values Mark H Weaver
  2 siblings, 1 reply; 9+ messages in thread
From: Mark H Weaver @ 2013-03-19  1:53 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 78 bytes --]

Here's an improved patch that updates the manual and adds tests.

     Mark



[-- Attachment #2: [PATCH] SRFI-45: Support delayed expressions that return multiple values --]
[-- Type: text/x-diff, Size: 7686 bytes --]

From 220fb56249b462ad1b205a45a4953e6dc857c96e Mon Sep 17 00:00:00 2001
From: Mark H Weaver <mhw@netris.org>
Date: Mon, 18 Mar 2013 20:01:12 -0400
Subject: [PATCH] SRFI-45: Support delayed expressions that return multiple
 values.

* 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.

* 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.
---
 doc/ref/srfi-modules.texi     |   53 ++++++++++++++++++++++++-----------------
 module/srfi/srfi-45.scm       |   16 +++++++------
 test-suite/tests/srfi-45.test |   34 ++++++++++++++++++++++++++
 3 files changed, 74 insertions(+), 29 deletions(-)

diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi
index af1afc0..099f27e 100644
--- a/doc/ref/srfi-modules.texi
+++ b/doc/ref/srfi-modules.texi
@@ -3833,45 +3833,54 @@ 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.
+
 @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 value ...
+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
+
+For expressions that return arbitrary numbers of values, we have the
+equivalence
+
+@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 +3890,7 @@ usage semantics specified above:
 @lisp
 (force (delay expression)) -> expression
 (force (lazy  expression)) -> (force expression)
-(force (eager value))      -> value
+(force (eager value ...))  -> value ...
 @end lisp
 
 @subsubheading Correct usage
diff --git a/module/srfi/srfi-45.scm b/module/srfi/srfi-45.scm
index 29b0393..a44cc97 100644
--- a/module/srfi/srfi-45.scm
+++ b/module/srfi/srfi-45.scm
@@ -1,6 +1,6 @@
 ;;; srfi-45.scm -- Primitives for Expressing Iterative Lazy Algorithms
 
-;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+;; Copyright (C) 2010, 2011, 2013 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, slightly
-;; modified to use SRFI-9.
+;; This is the code of the reference implementation of SRFI-45,
+;; modified to use SRFI-9 and to support multiple values.
 
 ;; This module is documented in the Guile Reference Manual.
 
@@ -50,16 +50,18 @@
 (define-syntax-rule (lazy exp)
   (make-promise (make-value 'lazy (lambda () exp))))
 
-(define (eager x)
-  (make-promise (make-value 'eager x)))
+(define (eager . xs)
+  (make-promise (make-value 'eager xs)))
 
 (define-syntax-rule (delay exp)
-  (lazy (eager exp)))
+  (lazy (call-with-values
+            (lambda () exp)
+          eager)))
 
 (define (force promise)
   (let ((content (promise-val promise)))
     (case (value-tag content)
-      ((eager) (value-proc content))
+      ((eager) (apply values (value-proc content)))
       ((lazy)  (let* ((promise* ((value-proc content)))
                       (content  (promise-val promise)))        ; *
                  (if (not (eqv? (value-tag content) 'eager))   ; *
diff --git a/test-suite/tests/srfi-45.test b/test-suite/tests/srfi-45.test
index 573eea0..d72de60 100644
--- a/test-suite/tests/srfi-45.test
+++ b/test-suite/tests/srfi-45.test
@@ -258,3 +258,37 @@
 ;; Commented out since it takes too long
 #;
 (test-equal 300000000 (force (times3 100000000)))    ;==> bounded space
+
+
+;======================================================================
+; Test memoization of multiple values (non-standard extension in Guile)
+
+(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))))
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH] SRFI-45: Support multiple values; add promise? predicate
  2013-03-19  1:53 ` Mark H Weaver
@ 2013-03-19  3:49   ` Mark H Weaver
  2013-03-19 13:25     ` Ludovic Courtès
  0 siblings, 1 reply; 9+ messages in thread
From: Mark H Weaver @ 2013-03-19  3:49 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 419 bytes --]

Apologies for the rapid-fire posts, but having looked at Racket's
SRFI-45 module, I see that they added 'promise?' to the list of exports,
and I think we should too.  As things stand now, (promise? (delay 1))
returns #f if you have imported SRFI-45, and that seems wrong.  If we
replace 'delay' and 'force', we should also replace 'promise?'.

Here's an updated patch.  Comments and suggestions solicited.

     Mark



[-- Attachment #2: [PATCH] SRFI-45: Support multiple values; add promise? predicate --]
[-- Type: text/x-diff, Size: 8338 bytes --]

From 1225cc23b9088e8d52a99f1bac2814b0905826ee Mon Sep 17 00:00:00 2001
From: Mark H Weaver <mhw@netris.org>
Date: Mon, 18 Mar 2013 20:01:12 -0400
Subject: [PATCH] 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.
---
 doc/ref/srfi-modules.texi     |   57 +++++++++++++++++++++++++----------------
 module/srfi/srfi-45.scm       |   21 ++++++++-------
 test-suite/tests/srfi-45.test |   40 +++++++++++++++++++++++++++++
 3 files changed, 87 insertions(+), 31 deletions(-)

diff --git a/doc/ref/srfi-modules.texi b/doc/ref/srfi-modules.texi
index af1afc0..c0d077b 100644
--- a/doc/ref/srfi-modules.texi
+++ b/doc/ref/srfi-modules.texi
@@ -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 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
+
+@deffn {Scheme Procedure} promise? obj
+Return true if @var{obj} is an SRFI-45 promise.
 @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
diff --git a/module/srfi/srfi-45.scm b/module/srfi/srfi-45.scm
index 29b0393..47e3ba6 100644
--- a/module/srfi/srfi-45.scm
+++ b/module/srfi/srfi-45.scm
@@ -1,6 +1,6 @@
 ;;; srfi-45.scm -- Primitives for Expressing Iterative Lazy Algorithms
 
-;; Copyright (C) 2010, 2011 Free Software Foundation, Inc.
+;; Copyright (C) 2010, 2011, 2013 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, slightly
-;; modified to use SRFI-9.
+;; This is the code of the reference implementation of SRFI-45,
+;; modified to use SRFI-9 and to support multiple values.
 
 ;; This module is documented in the Guile Reference Manual.
 
@@ -36,8 +36,9 @@
   #:export (delay
              lazy
              force
-             eager)
-  #:replace (delay force)
+             eager
+             promise?)
+  #:replace (delay force promise?)
   #:use-module (srfi srfi-9))
 
 (define-record-type promise (make-promise val) promise?
@@ -50,16 +51,18 @@
 (define-syntax-rule (lazy exp)
   (make-promise (make-value 'lazy (lambda () exp))))
 
-(define (eager x)
-  (make-promise (make-value 'eager x)))
+(define (eager . xs)
+  (make-promise (make-value 'eager xs)))
 
 (define-syntax-rule (delay exp)
-  (lazy (eager exp)))
+  (lazy (call-with-values
+            (lambda () exp)
+          eager)))
 
 (define (force promise)
   (let ((content (promise-val promise)))
     (case (value-tag content)
-      ((eager) (value-proc content))
+      ((eager) (apply values (value-proc content)))
       ((lazy)  (let* ((promise* ((value-proc content)))
                       (content  (promise-val promise)))        ; *
                  (if (not (eqv? (value-tag content) 'eager))   ; *
diff --git a/test-suite/tests/srfi-45.test b/test-suite/tests/srfi-45.test
index 573eea0..7771d09 100644
--- a/test-suite/tests/srfi-45.test
+++ b/test-suite/tests/srfi-45.test
@@ -258,3 +258,43 @@
 ;; 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))))
-- 
1.7.10.4


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [PATCH] SRFI-45: Support multiple values; add promise? predicate
  2013-03-19  3:49   ` [PATCH] SRFI-45: Support multiple values; add promise? predicate Mark H Weaver
@ 2013-03-19 13:25     ` Ludovic Courtès
  2013-03-19 17:55       ` Mark H Weaver
  0 siblings, 1 reply; 9+ messages in thread
From: Ludovic Courtès @ 2013-03-19 13:25 UTC (permalink / raw)
  To: guile-devel

Mark H Weaver <mhw@netris.org> skribis:

> From 1225cc23b9088e8d52a99f1bac2814b0905826ee Mon Sep 17 00:00:00 2001
> From: Mark H Weaver <mhw@netris.org>
> Date: Mon, 18 Mar 2013 20:01:12 -0400
> Subject: [PATCH] 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.

Looks good to me, of course.

> +;======================================================================
> +; Test promise? predicate (non-standard Guile extension)

The line is a bit baroque to my taste.  ;-)

Thanks,
Ludo’.




^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] SRFI-45: Support multiple values; add promise? predicate
  2013-03-19 13:25     ` Ludovic Courtès
@ 2013-03-19 17:55       ` Mark H Weaver
  0 siblings, 0 replies; 9+ messages in thread
From: Mark H Weaver @ 2013-03-19 17:55 UTC (permalink / raw)
  To: Ludovic Courtès; +Cc: guile-devel

Hi Ludovic,

ludo@gnu.org (Ludovic Courtès) writes:

> Mark H Weaver <mhw@netris.org> skribis:
>
>> From 1225cc23b9088e8d52a99f1bac2814b0905826ee Mon Sep 17 00:00:00 2001
>> From: Mark H Weaver <mhw@netris.org>
>> Date: Mon, 18 Mar 2013 20:01:12 -0400
>> Subject: [PATCH] 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.
>
> Looks good to me, of course.

Excellent, thanks.  I pushed a slightly improved version to stable-2.0.
(I also fixed the copyright notice on srfi-45.test).

>> +;======================================================================
>> +; Test promise? predicate (non-standard Guile extension)
>
> The line is a bit baroque to my taste.  ;-)

I'm not sure what you mean, but feel free to change it.

   Thanks,
     Mark



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] SRFI-45: Support delayed expressions that return multiple values
  2013-03-19  1:08 ` Ian Price
@ 2013-03-19 18:24   ` Mark H Weaver
  0 siblings, 0 replies; 9+ messages in thread
From: Mark H Weaver @ 2013-03-19 18:24 UTC (permalink / raw)
  To: Ian Price; +Cc: guile-devel

Hi Ian,

Ian Price <ianprice90@googlemail.com> writes:

> Mark H Weaver <mhw@netris.org> writes:
>
>> Any objections to pushing this to stable-2.0?
>
> Change is simple enough, and it matches the behaviour of built-in
> force/delay. Should be a rubber stamp IMO :)

Agreed :)

> I note Eli Barzilay contributed some changes in the post-finalisation
> archive for srfi 45 to support multiple values.

Ah, thanks for pointing that out.  Unfortunately, all three of his
proposals were incompatible with SRFI-45, and were not adopted anywhere
as far as I can tell (not in Racket at least).  His least incompatible
proposal changed 'eager' into a macro, so that it could accept a single
expression that returns multiple values.

It's too bad no one proposed supporting multiple values before SRFI-45
was finalized.  As it is, this is the best we can do while remaining
compatible with SRFI-45.

    Thanks,
      Mark



^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] SRFI-45: Support delayed expressions that return multiple values
  2013-03-19  0:30 [PATCH] SRFI-45: Support delayed expressions that return multiple values Mark H Weaver
  2013-03-19  1:08 ` Ian Price
  2013-03-19  1:53 ` Mark H Weaver
@ 2013-03-26 10:32 ` Mark H Weaver
  2013-03-26 21:55   ` Ludovic Courtès
  2 siblings, 1 reply; 9+ messages in thread
From: Mark H Weaver @ 2013-03-26 10:32 UTC (permalink / raw)
  To: guile-devel

[-- Attachment #1: Type: text/plain, Size: 562 bytes --]

Hello all,

After some discussion with Eli Barzilay on the SRFI-45 mailing list [1],
I've come to believe it's a mistake to extend it in a suboptimal way.
'eager' should have the same API as 'delay'.  I'd rather do the job
right, even if that means moving it to a different module.

I think we should back out this change to SRFI-45.  The only thing I
think we should keep is the addition of 'promise?' to the list of
exports (as is done in Racket).

What do other people think?

      Mark

[1] http://srfi.schemers.org/srfi-45/post-mail-archive/maillist.html


[-- Attachment #2: Type: message/rfc822, Size: 1744 bytes --]

From: Mark H Weaver <mhw@netris.org>
To: Eli Barzilay <eli@barzilay.org>
Cc: srfi-45@srfi.schemers.org
Subject: Re: Compatible support for multiple values in SRFI-45
Date: Tue, 26 Mar 2013 06:14:18 -0400
Message-ID: <871ub2a2o5.fsf@tines.lan>

Hi Eli,

Eli Barzilay <eli@barzilay.org> writes:

> 30 minutes ago, Mark H Weaver wrote:
>> 
>> I agree that it's unfortunate to destroy the symmetry between
>> 'eager' and 'delay', but I see no way to support multiple values
>> without either destroying that symmetry or breaking compatibility
>> with SRFI-45.
>
> IMO, having a good, uniform API is *far* more important than keeping
> `eager' a function. [...]
>
>> If you can suggest a better way to add support for multiple values
>> that is compatible with SRFI-45, I'd be glad to hear it.
>
> Write a new short srfi which will say "same as srfi-45, except that
> `eager' is a macro", then add multiple values.  Seriously.

Having thought more on this, I've come to agree with you.  It's a
mistake to bend over backwards to remain compatible with SRFI-45.
It's more important to promote the best API we can come up with.

Users wouldn't be able to rely on SRFI-45 having my proposed extension
anyway.  I think we will abandon this proposed extension for Guile, and
leave SRFI-45 alone.

Maybe it _is_ time for a new SRFI.

     Thanks,
       Mark


^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [PATCH] SRFI-45: Support delayed expressions that return multiple values
  2013-03-26 10:32 ` [PATCH] SRFI-45: Support delayed expressions that return multiple values Mark H Weaver
@ 2013-03-26 21:55   ` Ludovic Courtès
  0 siblings, 0 replies; 9+ messages in thread
From: Ludovic Courtès @ 2013-03-26 21:55 UTC (permalink / raw)
  To: guile-devel

Mark H Weaver <mhw@netris.org> skribis:

> I think we should back out this change to SRFI-45.  The only thing I
> think we should keep is the addition of 'promise?' to the list of
> exports (as is done in Racket).

[...]

> Having thought more on this, I've come to agree with you.  It's a
> mistake to bend over backwards to remain compatible with SRFI-45.
> It's more important to promote the best API we can come up with.
>
> Users wouldn't be able to rely on SRFI-45 having my proposed extension
> anyway.  I think we will abandon this proposed extension for Guile, and
> leave SRFI-45 alone.

Makes sense.

What about adding (srfi srfi-45 gnu) with the extension?

Ludo’.




^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2013-03-26 21:55 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2013-03-19  0:30 [PATCH] SRFI-45: Support delayed expressions that return multiple values Mark H Weaver
2013-03-19  1:08 ` Ian Price
2013-03-19 18:24   ` Mark H Weaver
2013-03-19  1:53 ` Mark H Weaver
2013-03-19  3:49   ` [PATCH] SRFI-45: Support multiple values; add promise? predicate Mark H Weaver
2013-03-19 13:25     ` Ludovic Courtès
2013-03-19 17:55       ` Mark H Weaver
2013-03-26 10:32 ` [PATCH] SRFI-45: Support delayed expressions that return multiple values Mark H Weaver
2013-03-26 21:55   ` Ludovic Courtès

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).