Stream-filter and space leaks
Phil Bewig
(20 Feb 2003 14:08 UTC)
|
Re: Stream-filter and space leaks
Richard Kelsey
(20 Feb 2003 18:41 UTC)
|
Re: Stream-filter and space leaks
Phil Bewig
(21 Feb 2003 09:57 UTC)
|
Re: Stream-filter and space leaks
Richard Kelsey
(21 Feb 2003 23:18 UTC)
|
Re: Stream-filter and space leaks
sperber@xxxxxx
(21 Feb 2003 10:04 UTC)
|
Re: Stream-filter and space leaks Richard Kelsey (21 Feb 2003 15:06 UTC)
|
Re: Stream-filter and space leaks
Matthias Neubauer
(25 Feb 2003 16:01 UTC)
|
Re: Stream-filter and space leaks
Richard Kelsey
(25 Feb 2003 18:25 UTC)
|
Re: Stream-filter and space leaks
Matthias Neubauer
(25 Feb 2003 21:32 UTC)
|
Re: Stream-filter and space leaks
Richard Kelsey
(25 Feb 2003 22:11 UTC)
|
Re: Stream-filter and space leaks
sperber@xxxxxx
(26 Feb 2003 08:18 UTC)
|
Re: Stream-filter and space leaks
Matthias Neubauer
(26 Feb 2003 13:31 UTC)
|
Re: Stream-filter and space leaks
sperber@xxxxxx
(11 Mar 2003 14:58 UTC)
|
Re: Stream-filter and space leaks
Matthias Neubauer
(19 Mar 2003 15:27 UTC)
|
Re: Stream-filter and space leaks
felix
(22 Mar 2003 09:49 UTC)
|
Re: Stream-filter and space leaks
felix
(22 Mar 2003 09:56 UTC)
|
From: xxxxxx@informatik.uni-tuebingen.de (Michael Sperber [Mr. Preprocessor]) Date: Fri, 21 Feb 2003 11:04:03 +0100 The code you posted seems to be essentially the definition of DELAY/FORCE from Scheme 48. However, Phil's old code does leak in Scheme 48 and doesn't leak with the proposed fix. Right. I was mistaken about the source of the leak. This time around I have actually tested the code. The problem is that the Scheme 48 version of DELAY, as well as the R5RS version, keeps the delayed thunk around in case it is reentrant: > (define f (let ((first? #t)) (delay (if first? (begin (set! first? #f) (force f)) 'second)))) ; no values returned > (force f) 'second In the case of the SRFI version of STREAM-FILTER the thunk is closed over the filtered stream. The new version drops that thunk's reference to the stream before forcing it. DELAY and FORCE can be modified to plug the leak, at the cost of making promises non-reentrant. In the version below the promise's thunk clears the promise's reference to itself before executing the closed-over expression. The SRFI's version of STREAM-FILTER doesn't leak when using MY-DELAY and MY-FORCE. (define-syntax my-delay (syntax-rules () ((delay ?exp) (make-promise (lambda (clear-me) (set-car! clear-me #f) ?exp))))) (define (make-promise thunk) (let ((already-run? #f) (thunk-then-result (list thunk))) (lambda () (if already-run? (car thunk-then-result) (cond ((procedure? (car thunk-then-result)) (let ((result ((car thunk-then-result) thunk-then-result))) (cond ((not already-run?) (set! already-run? #t) (set-car! thunk-then-result result))) (car thunk-then-result))) (else (error "circular promise"))))))) (define (my-force promise) (promise)) As promised, promises are no longer reentrant: > (define g (let ((first? #t)) (my-delay (if first? (begin (set! first? #f) (my-force g)) 'second)))) ; no values returned > (my-force g) Error: circular promise 1> This might be acceptable for streams. This is just a note---I intend to check next week why this is so. I was unwilling to wait... -Richard