#lang racket ; based on SICP section 3.5, but shorter and more consistent names ; base implementation of streams, everything we define here is visible ; to the user of the module, and we also further export the 5 primative ; operations necessary to streams: s-cons, s-first, s-rest. (require "stream-primatives.rkt") (provide (all-defined-out)) (provide s-cons) (provide s-first) (provide s-rest) (provide s-empty) (provide s-null?) ; index into a stream, 0 origin (define (s-ref s n) (if (<= n 0) (s-first s) (s-ref (s-rest s) (- n 1)))) ; map over 1 stream (define (s-map-1 proc s) (if (s-null? s) s-empty (s-cons (proc (s-first s)) (s-map-1 proc (s-rest s))))) ; generalized map over n streams (define (s-map proc . argstreams) (if (s-null? (first argstreams)) s-empty (s-cons (apply proc (map (lambda (e) (s-first e)) argstreams)) (apply s-map (cons proc (map (lambda (e) (s-rest e)) argstreams)))))) ; eval proc for its side-effects on each term of the stream (define (s-for-each proc s) (if (s-null? s) 'done (begin (proc (s-first s)) (s-for-each proc (s-rest s))))) ; generate the stream of integers: low low+1 ... high (define (s-enumerate-interval low high) (if (> low high) s-empty (s-cons low (s-enumerate-interval (+ low 1) high)))) ; filter a stream, returning a stream that contains only the elements that ; satisfy pred (define (s-filter pred s) (cond ((s-null? s) s-empty) ((pred (s-first s)) (s-cons (s-first s) (s-filter pred (s-rest s)))) (else (s-filter pred (s-rest s))))) ; normal non-stream function that generates integers: low low+1 ... high (define (enumerate-interval low high) (if (> low high) '() (cons low (enumerate-interval (+ low 1) high)))) ; display the elements of the stream from ... to, ; the usual 0 origin indexing. (define (s-interval-to-list s from to) (map (lambda (i) (s-ref s i)) (enumerate-interval from to)) )