[plt-scheme] Re: srfi 41 for PLT

From: Jos Koot (jos.koot at telefonica.net)
Date: Mon Feb 18 21:19:16 EST 2008

----- Original Message ----- 
From: "Chongkai Zhu" <czhu at cs.utah.edu>
To: "Jos Koot" <jos.koot at telefonica.net>
Sent: Tuesday, February 19, 2008 2:04 AM
Subject: Re: srfi 41 for PLT

> Please explain (to the list). Many thanks.
> Chongkai
> Eli Barzilay wrote:
>> On Feb 15, Jos Koot wrote:
>>> 1: there is still a problem with the van Tonder promises as now
>>> implemented in PLT Scheme.
>> What problem?

Below is my conversation with Phil Bewig on this. It clearly shows the 
problem. In the conversation with Phil Bewig with 'Eli's version' I mean:

(define (force promise)
  (let ((p (promise-p promise)))
    (cond ((procedure? p) (let ((promise* (p)))
                            (if (not (pair? (promise-p promise)))
                                (begin (set-promise-p! promise (promise-p 
                                       (set-promise-p! promise* promise)))
                            (force promise)))
          ((pair? p)      (car p))
          ((promise? p)   (force p))
          (else           (error "Not a promise")))))

The cond-clause ((promise? p) (force p)) does not lift. Reading back the 
post-finalization discussion of srfi 45 again, it is not quite clear to me 
whether the above code comes from Eli Barzilay or from Andre van Tonder. 
Anyway, as far as I know the current implementation in PLT is based on the 
above code (generalized for multiple values by Eli Barzilay and prohibiting 
a promise to be forced while being forced) As Eli has pointed out, the 
solution I give below is not nice, for a force call is made in non-tail 
position. Phil Bewig decided to return to the original srfi 45 in the form 
as it was finalized. I think that is good for srfi 41. Phil Bewig has used 
other names for the syntaxes and procedures, but the correspondence is clear 
I think.

See also the post finalization discussion of srfi 45. Hope this explains 
Jos Koot

On Nov 9, 2007 9:01 AM, Jos Koot <jos.koot at telefonica.net> wrote:

  I ran the unit-test in both versions with profiling:
  With Eli's    promises: stream-force is called 7065035 times. (= according 
to code above)
  With original promises: stream-force is called  392874 times. (= according 
to srfi 45 as it was finalized)

  The reason for this big difference is in the representation of the 
promises and the fact that Eli's stream-force does not lift the content of a 
promise if that content is a stream. More specifically: consider a promise A 
containing a stream B. The content of B is not lifted into A (second cond 
clause in stream-force) This can be fixed as follows:

    (define (stream-force prom)
      (let ((p (stream-promise prom)))
        (cond ((pair? p)   (car p))
              ((stream? p)
               (let ((x (stream-force p))) ; <== non-tail call as indicated 
by Eli Barzilay.
                 (stream-promise! prom (list x))
              ((procedure? p)
               (let ((prom* (p)))
                 (if (not (pair? (stream-promise prom)))
                     (if (stream? prom*)
                       (begin (stream-promise! prom (stream-promise prom*))
                              (stream-promise! prom* prom))
                       (stream-promise! prom (list prom*))))
                 (stream-force prom)))
              (else        (error 'stream-force "invalid promise")))))

  With this version stream-force is called 392979 times.


  ((((lambda(x)((((((x x)x)x)x)x)x))
     (lambda(x)(lambda(y)(x(x y)))))
    (lambda(x)(write x)x))
    ----- Original Message ----- 
    From: Phil Bewig
    To: Jos Koot
    Sent: Friday, November 09, 2007 2:40 PM
    Subject: Re: 2streams

    Wow!  Why?

    On Nov 9, 2007 5:02 AM, Jos Koot <jos.koot at telefonica.net> wrote:

      (time (unit-test)) original promises
      cpu time: 1032 real time: 1219 gc time: 93

      (time (unit-test)) Eli's promises
      cpu time: 9203 real time: 9453 gc time: 0


Posted on the users mailing list.