Re: simpler srfi 45 implementation Eli Barzilay 13 Nov 2007 12:44 UTC

On Nov 13, Jos Koot wrote:
> Eli wrote the following version:
>
> [...]
>   (define (force promise)
>     (let ([p (promise-p promise)])
>       (cond [(procedure? p)
>              (let ([promise* (p)])
>                (unless (pair? (promise-p promise))
>                  (if (promise? promise*)
>                    (begin (set-promise-p! promise (promise-p promise*))
>                           (set-promise-p! promise* promise))
>                    (set-promise-p! promise (list promise*))))
>                (force promise))]
>             [(pair? p)    (car p)]
>             [(promise? p) (force p)] <----
>             [else         (error "Invalid promise, contains" p)]))))
> [...]

Actually, I use a variation of that, which you can see at

  http://svn.plt-scheme.org/plt/trunk/collects/lazy/promise.ss

(The file has four versions of `force' : the first is like the above,
the second deals with multiple values, the third deals with multiple
values only for the delay/force case, and the last adds exception
catching.)

The differences between this and the version that you quoted are
mostly technicalities, and the code that I have can still use this
optimization.  I couldn't verify that the version I'm using enjoys the
same speedup -- Phil: do you have the code needed to run Jos's example?

... and there's a "BUT":

I was aware of the possible optimization at the time, but didn't find
any example where it mattered.  However, if you do put it in:

>             [(promise? p)
>              (let* ((v (force p)))
>               (if (not (pair? (promise-p prom)))
>                   (set-promise-p! prom (list v)))
>               (car (promise-p prom)))]

then you do the recursive forcing of `p' in a non-tail conext.  My
(vague, not formal at all) feeling about these "referral promises" is
that they do happen in places where the original code had a tail call,
so it might be a bad idea to break it.

So I don't know whether it should be included or not -- do you see
that it's not doing any damage?

--
          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                  http://www.barzilay.org/                 Maze is Life!