Eli wrote the following
version:
(module lazy1
mzscheme-no-promises
(provide lazy delay force
promise?)
(define-struct promise (p))
(define-syntax
lazy
(syntax-rules ()
[(lazy exp) (make-promise (lambda () exp))]))
(define-syntax
delay
(syntax-rules ()
[(delay exp) (lazy (make-promise (list exp)))]))
(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)]))))
When Phil Bewig tried this for his SRFI-41,
a substantial slow down (factor 100) was found for:
(stream-ref
(stream-of (list a b
c)
(n in (stream-from
1))
(a in (stream-range 1
n))
(b in (stream-range a
n))
(c is (- n a
b))
(= (+ (* a a) (* b b)) (* c
c)))
50)
Phil asked me what was wrong. The problem is in the cond-clause marked
with <---- in the above code. The promise is not lifted. After replacing the marked cond-clause as follows, things ran as fast as
before:
[(promise?
p)
(let* ((v (force
p)))
(if (not (pair? (promise-p
prom)))
(set-promise-p! prom (list
v)))
(car (promise-p prom)))]
Jos Koot
((((lambda(x)((((((x
x)x)x)x)x)x))
(lambda(x)(lambda(y)(x(x y)))))
(lambda(x)(write x)x))
'greeting)