guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH] SRFI-45: Support delayed expressions that return multiple values


From: Mark H Weaver
Subject: [PATCH] SRFI-45: Support delayed expressions that return multiple values
Date: Mon, 18 Mar 2013 20:30:26 -0400

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


>From bbaca34ea0158ad84e692d631ee8efc85a18b81e Mon Sep 17 00:00:00 2001
From: Mark H Weaver <address@hidden>
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


reply via email to

[Prev in Thread] Current Thread [Next in Thread]