A bug in the reference implementation Shiro Kawai 18 Nov 2005 10:48 UTC

The current reference implementation seems to have a bug in
stream-filter.  Currently it is implemented as follows:

;; STREAM-FILTER pred? stream -- new stream including only items passing pred?
(define (stream-filter pred? strm)
  (cond ((not (procedure? pred?)) (stream-error "non-functional argument to stream-filter"))
        ((not (stream? strm)) (stream-error "attempt to apply stream-filter to non-stream"))
        (else (stream-unfoldn
                (lambda (s)
                  (values
                    (stream-cdr s)
                    (cond ((stream-null? s) '())
                          ((pred? (stream-car s)) (list (stream-car s)))
                          (else #f))))
                strm
                1))))

The closure passed to stream-unfoldn doesn't check whether
's' is stream-null before taking stream-cdr of it, so it
signals an error if you attempt to read the end of the
stream created by stream-filter.  You can see it by
evaluating this expression:

  (stream-null? (stream-filter values (stream)))

A possible fix is to replace the closure for something like this:

               (lambda (s)
                 (cond
                  ((stream-null? s)
                   (values stream-null '()))
                  ((pred? (stream-car s))
                   (values (stream-cdr s) (list (stream-car s))))
                  (else
                   (values (stream-cdr s) #f))))

--shiro