[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

A bug in the reference implementation

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)
                    (stream-cdr s)
                    (cond ((stream-null? s) '())
                          ((pred? (stream-car s)) (list (stream-car s)))
                          (else #f))))

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)
                  ((stream-null? s)
                   (values stream-null '()))
                  ((pred? (stream-car s))
                   (values (stream-cdr s) (list (stream-car s))))
                   (values (stream-cdr s) #f))))