download original
  
;--------interface------------
;; primitives:
; empty-stream
; (stream-empty? s)
; (make-stream head tail-stream)
; (stream-head s)
; (stream-tail s)
; axioms:
;  (stream-head (make-stream head tail-stream)) == head
;  (stream-tail (make-stream head tail-stream)) == tail-stream
;  (stream-head empty-stream) == <undefined>
;  (stream-tail empty-stream) == <undefined>
;  (stream-empty? empty-stream) == #t
;  (stream-empty? (make-stream head tail-stream)) == #f
; utilities:
; (take-first n s)   => stream
; (stream-map mapping-proc s)   => stream
; (stream-accumulate combiner-proc startval s)  => object (return value of proc)
; (stream-filter filter-proc s)  => stream
; various constructors:
; (make-loop-stream startval incrementor continue-pred)
; (make-int-interval-stream start stop)  ; if (null? stop): infinite stream starting at start
;--------representation-------
; - uses "lazy evaluation":
; - the empty stream is '()
; - a nonempty stream is a cons whose car is the stream's head, and whose cdr is a
;     procedure of 0 arguments that returns the stream's tail (which is again a stream)
;(use-syntax (ice-9 syncase))   ; for Guile
;helpers (Scheme doesn't define them)
(define (1+ x) (+ x 1))
(define (1- x) (- x 1))
(define empty-stream '())
(define stream-empty? null?)
(define-syntax make-stream
  (syntax-rules ()
                ((make-stream head tail)
                 (cons head (delay tail)))))
;(define-syntax make-stream
;  (syntax-rules ()
;                ((make-stream head tail)
;                 (cons head (lambda () tail)))))
(define stream-head car)
(define (stream-tail s)
  (force (cdr s)))
;(define (stream-tail s)
;  ((cdr s)))
;;TODO: tail recursiveness
(define (take-first n s)
  (cond ((<= n 0) empty-stream)
        ((stream-empty? s) empty-stream)
        (else
         (make-stream
          (stream-head s)
          (take-first (1- n) (stream-tail s))))))
(define (take-nth n s)
  (if (= n 0)
      (stream-head s)
      (take-nth (1- n) (stream-tail s))))
(define (stream-map mapping-proc s)
  (if (stream-empty? s)
      empty-stream
      (make-stream (mapping-proc (stream-head s))
                   (stream-map mapping-proc (stream-tail s)))))
;; don't use for infinite streams...
(define (stream-accumulate combiner-proc startval s)
  (if (stream-empty? s)
      startval
      (stream-accumulate combiner-proc
                         (combiner-proc startval (stream-head s))
                         (stream-tail s))))
;; don't use for infinite streams...
(define (stream-to-list s)
  (stream-accumulate (lambda (x y) (cons y x)) '() s))
(define (stream-length s)
  (stream-accumulate (lambda (curr-length obj) (1+ curr-length)) 0 s))
(define (stream-filter filter-proc s)
  (if (stream-empty? s)
      empty-stream
      (let ((h (filter-proc (stream-head s))))
        (if h
            (make-stream (stream-head s) (stream-filter filter-proc
                                                        (stream-tail s)))
            (stream-filter filter-proc
                           (stream-tail s))))))
(define (stream-append s1 s2)
  (if (stream-empty? s1)
      s2
      (make-stream (stream-head s1)
                   (stream-append (stream-tail s1)
                                  s2))))
(define (stream-flatten1 s)
  (stream-accumulate stream-append empty-stream s))
(define (make-loop-stream startval incrementor continue-pred)
  (if (not (continue-pred startval))
      empty-stream
      (make-stream
       startval
       (make-loop-stream (incrementor startval) incrementor continue-pred))))
(define (make-int-interval-stream start stop)
  (make-loop-stream start
                    1+
                    (lambda (x) (or (null? stop)
                                    (<= x stop)))))
; all natural numbers (infinite stream)
(define naturals-stream
  (make-int-interval-stream 0 '()))
  
   back to test 
  
  (C) 1998-2017 Olaf Klischat  <olaf.klischat@gmail.com>