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

RE: streams



Here's an implementation of streams in MzScheme. It's a bit wierd because I
wanted it to run (a) in a Common Lisp compatibility package I wrote, and (b)
it was like some other code we'd originally written in CL (based on Peter
Novig's code). I *think* it implements a superset of the SICP stream
procedures. It it formats badly in email, I'll send a text file directly on
request.


(define the-empty-stream '())
(define stream-null? null?)

(define-macro stream-delay
  (lambda (computation)
    `(lambda () ,computation)))

;; we don't use DELAY for CL compatibility...
(define-macro cons-stream
  (lambda (the-car the-cdr)
    `(cons ,the-car (stream-delay ,the-cdr))))

(define (stream-car stream) (car stream))

;; unlike sicp, but like Norvig, we change the stream on stream-cdr
(define (stream-cdr stream)
  (let ((theCdr (cdr stream)))
    (when (procedure?  theCdr)
      (set-cdr! stream (theCdr)))
    (cdr stream)))

(define (stream-ref s n)
  (if (< n 0)
    (error "Invaid STREAM-REF index:" n)
    (if (= n 0)
      (stream-car s)
      (stream-ref (stream-cdr s) (- n 1)))))

(define (stream-enumerate-interval low high)
  (if (> low high)
    the-empty-stream
    (cons-stream low
                 (stream-enumerate-interval (+ low 1) high))))

(define (stream-filter pred stream)
  (cond ((stream-null? stream) the-empty-stream)
        ((pred (stream-car stream))
         (cons-stream (stream-car stream)
                      (stream-filter pred (stream-cdr stream))))
        (else (stream-filter pred (stream-cdr stream)))))

(define (stream-filtering pred stream)
  "runs pred, keeps if non-#f"
  (if (stream-null? stream) the-empty-stream
      (let ((val (pred (stream-car stream))))
        (if val (cons-stream val (stream-filtering pred (stream-cdr
stream)))
        (stream-filtering pred (stream-cdr stream))))))


(define (stream-map proc stream)
  (cond ((stream-null? stream) the-empty-stream)
        (else (cons-stream (proc (stream-car stream))
                           (stream-map proc (stream-cdr stream))))))

(define (stream-append stream1 stream2)
  (if (stream-null? stream1) stream2
      (cons-stream (stream-car stream1)
                   (stream-append (stream-cdr stream1) stream2))))

(define (stream-append-filtering pred stream)
  "Map pred over stream, delaying all but the first pred call,
   appending results, filtering along the way"
  (if (stream-null? stream)
    the-empty-stream
    (let* ((head (stream-car stream))
           (tail (stream-cdr stream))
           (result (pred head)) )
      (if (not (stream-null? result))
        (cons-stream (stream-car result)
                   (stream-append (stream-cdr result)
                                 (stream-append-filtering pred tail)))
        (stream-append-filtering pred tail)))))

(define (stream-for-each proc stream)
  (cond ((stream-null? stream) (values))
        (else (proc (stream-car stream))
              (stream-for-each proc (stream-cdr stream)))))

(define (stream-force stream)
  (stream-for-each (lambda (i) i) stream)
  stream)

; take the first (upto) n items from stream.
(define (stream-take stream count)
  (if (or (<= count 0) (stream-null? stream))
    '()
      (cons (stream-car stream)
            (stream-take (stream-cdr stream) (- count 1)))))

;; some useful streams

(define (integers-starting-from n)
  (cons-stream n (integers-starting-from (+ n 1))))

(define integers (integers-starting-from 1))


> -----Original Message-----
> From: owner-plt-scheme@fast.cs.utah.edu
> [mailto:owner-plt-scheme@fast.cs.utah.edu]On Behalf Of ktpr
> Sent: Thursday, October 26, 2000 12:58 PM
> To: Shriram Krishnamurthi
> Cc: plt-scheme@fast.cs.utah.edu
> Subject: Re: streams
>
>
>
>
> Shriram Krishnamurthi wrote:
> >
> > You can easily add streams with a few instructions.  Maybe your
> > instuctor already has these handy?  (Are you taking a course at BU?
> > If so, can you send me your course home page URL?  Thanks!)
>
>
> Thank you both for you quick reply. I was afraid that the list was dead
> or something and I would get no support.
>
> 	My course's home page is at
> http://www.cs.bu.edu/faculty/kfoury/CS320-Fall00/home.html
> My teacher has not provided any implementation for Dr. Scheme and
> probably does not intend to. He uses MIT scheme, whose win32 package is
> pretty ugly.
>
> 	To implement streams I would need an implementation of head
> and tail. I
> understand that a thunk would be used in the implementation of tail. I
> would have to use "promise" in tail to allow for lazy evaluation. I am
> sure the implementation isn't has simple as
>
> [rough pseudo]
> 	(cond ((stream-car) (car lst))
> 	     ((stream-cdr) (display cadr lst "promise"))
> 	     (else display "error"))
>
> 	And i suspect it goes a little more low level than i have
> time for to
> do this assignment involving streams. Since this is not a homework
> problem in itself, this request for an implementation is not cheating
> (at least in my view). (Alternatively, I could just use the MIT win32
> version of Scheme.) So here it is: Could someone be so kind as to
> provide me with a stream implementation or direct me to a library that
> already has one.
>
> 	In any case, any help would be appreciated.
>
> thank you for your time,
> ktpr
>