An implementation of SRFI 40, A Library of Streams. Streams are a way of representing and computing with infinite sequences. In addition to providing standard library procedures for working with streams, this implementation includes and is based on new definitions for the lazy evaluation primitives delay and force and a new primitive called lazy. These definitions have the advantage over the traditional ones of being safe-for-space. For details see SRFI 45, Primitives for expressing iterative lazy algorithms.
Note also that SRFI 40 specifies even streams rather than the odd streams traditionally used in Scheme and found in books like Structure and Interpretation of Computer Programs. See the text of the SRFI for what this means and the implications.
Using this extension does not modify the native bindings for delay and force as the new versions are encapsulated within this implementation.
Based on the original SRFI 40 reference implementation by Philip L. Bewig and Andre von Tonder, modified for Chicken by Category 5.
SRFI 40 provides the following values and procedures:[constant] stream-null
The distinguished null stream.[procedure] (stream? object)
#t if object is a stream, #f otherwise.[procedure] (stream-cons object stream)
The primitive stream constructor.[procedure] (stream-null? object)
#t if object is the null stream, #f otherwise.[procedure] (stream-pair? object)
#t if object is a non-null stream, #f otherwise.[procedure] (stream-car stream)
First element of stream.[procedure] (stream-cdr stream)
Remaining elements of stream after the first.[procedure] (stream-delay object)
SRFI 40 delay.[procedure] (stream object ...)
Returns a new stream whose elements are object ....[procedure] (stream-unfoldn generator seed n)
Returns n+1 streams from (generator seed).[procedure] (stream-map proc stream ...)
Returns the stream produced by applying proc to each element of stream.[procedure] (stream-for-each proc stream ...)
Applies proc to each element of stream for side-effects.[procedure] (stream-filter pred? stream)
Returns a new stream consisting of the elements of stream for which pred? returns true.
(define stream-ref (lambda (s n) (let loop ((s s) (i 0)) (if (= i n) (stream-car s) (loop (stream-cdr s) (+ i 1)))))) (define stream-take (lambda (n s) (if (= n 0) '() (cons (stream-car s) (stream-take (- n 1) (stream-cdr s)))))) (define integers-from (lambda (n) (stream-cons n (integers-from (+ n 1))))) (define integers (integers-from 0)) (define divisible? (lambda (n k) (zero? (modulo n k)))) (define sieve (lambda (s) (stream-cons (stream-car s) (sieve (stream-filter (lambda (n) (not (divisible? n (stream-car s)))) (stream-cdr s)))))) (define primes (sieve (integers-from 2))) (stream-take 10 primes) => (2 3 5 7 11 13 17 19 23 29) (stream-ref primes 200) => 1229
(define mul-streams (lambda (s1 s2) (stream-cons (* (stream-car s1) (stream-car s2)) (mul-streams (stream-cdr s1) (stream-cdr s2))))) (define integer-reciprocals (lambda () (let loop ((s (stream-cdr integers))) (stream-cons (/ 1 (stream-car s)) (loop (stream-cdr s)))))) (define integrate-series (lambda (s) (mul-streams s (integer-reciprocals)))) (define exp-series (stream-cons 1 (integrate-series exp-series))) (define partial-sums (lambda (s) (let loop ((s s) (a 0)) (stream-cons (+ a (stream-car s)) (loop (stream-cdr s) (+ a (stream-car s))))))) (stream-ref (partial-sums exp-series) 20) => 2.71828182845905
- 1.6 (Ivan Raikov) Added options to the compilation command to generate exports file.
- 1.5 (Alejandro Forero Cuervo) Removed call to (register-feature! 'srfi-40), which was confusing require-extension
- 1.4 Fixed bug in stream-filter
- 1.3 make-stream is hidden (but still exported)
- 1.2 Some fixes to the basic stream handling were applied by Alejandro Forero Cuervo.
- 1.1 Adapted to new setup scheme.
- 1.0 Initial release
Copyright (C) 2003 by Philip L. Bewig of Saint Louis, Missouri, United States of America. All rights reserved.