;streams

(define the-empty-stream ())

(define stream-null? null?)

(define empty-stream? stream-null?)

(define-syntax cons-stream
  (syntax-rules () ((cons-stream val expr) (cons val (delay expr)))))

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

(define (stream-cdr stream) (force (cdr stream)))

(define (stream-ref stream n)
  (if (= n 0)
      (stream-car stream)
      (stream-ref (stream-cdr stream) (- 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-display stream n)
  (if (or (= n 0) (stream-null? stream))
      (newline)
      (begin (display " ")
             (display (stream-car stream))
             (stream-display (stream-cdr stream) (- n 1)))))

(define fstream1 (cons-stream 1 (cons-stream 3 (cons-stream 5
  (cons-stream 5 (cons-stream 7 the-empty-stream))))))

(define fstream2 (cons-stream 1 (cons-stream 2 (cons-stream 3
  (cons-stream 4 (cons-stream 5 (cons-stream 6 (cons-stream 7
  (cons-stream 8 the-empty-stream)))))))))

(define lstream1 (stream-filter even?
                                (stream-enumerate-interval 0
                                                           10000)))

(define lstream2 (stream-filter (lambda (n) (= (remainder n 3) 0))
                                (stream-enumerate-interval 0
                                                           10000)))

