Next: streams cons, Up: streams [Index]
The basic API provides two mutually–recursive abstract data types: An object of the ‘stream’ abstract data type is a promise that, when forced, is either ‘stream-null’ or is an object of type ‘stream-pair’. An object of the ‘stream-pair’ abstract data type contains a kar and a kdr, which must be a ‘stream’. The essential feature of streams is the systematic suspensions of the recursive promises between the two data types.
alpha stream :: (promise stream-null) | (promise (alpha stream-pair)) alpha stream-pair :: (promise alpha) x (promise (alpha stream))
The object stored in the kar of a ‘stream-pair’ is a promise that is forced the first time the kar is accessed; its value is cached in case it is needed again. The object may have any type, and different stream elements may have different types. If the kar is never accessed, the object stored there is never evaluated. Likewise, the kdr is a promise to return a stream, and is only forced on demand.
This API provides eight operators: constructors for ‘stream-null’ and ‘stream-pair’, type recognisers for streams and the two kinds of streams, accessors for both fields of a ‘stream-pair’, a lambda that creates procedures that return streams.
Return a promise that, when forced, is a single object, distinguishable
from all other objects, that represents the null stream.
stream-null
is immutable and unique.
Accept an object and a stream and create a newly–allocated stream
containing a promise that, when forced, is a ‘stream-pair’ with the
object in its kar and the stream in its stream-cdr
.
Once created, a ‘stream-pair’ is immutable; there is no
stream-set-kar!
or stream-set-kdr!
that modifies an
existing ‘stream-pair’. There is no dotted–pair or improper
stream as with lists.
Return #t
if obj is a ‘stream’ and #f
otherwise.
If obj is a ‘stream’, stream?
does not force its
promise.
If (stream? obj)
is #t
, then one of (stream-null?
obj)
and (stream-pair? obj)
will be #t
and the other will
be #f
; if (stream? obj)
is #f
, both
(stream-null? obj)
and (stream-pair? obj)
will be
#f
.
Return #t
if the obj is the distinguished null stream and
#f
otherwise. If obj is a ‘stream’,
stream-null?
must force its promise in order to distinguish
‘stream-null’ from ‘stream-pair’.
Take an obj and return #t
if it is a ‘stream-pair’
constructed by stream-cons
and #f
otherwise. If obj
is a ‘stream’, stream-pair?
must force its promise in order
to distinguish ‘stream-null’ from ‘stream-pair’.
Return the object stored in the kar of stream. stream-car
signals an error if the object passed to it is not a ‘stream-pair’.
Calling stream-car
causes the object stored there to be evaluated
if it has not yet been; the object’s value is cached in case it is
needed again.
Return the stream stored in the kdr of stream. stream-cdr
signals an error if the object passed to it is not a ‘stream-pair’.
Calling stream-cdr
does not force the promise containing the
stream stored in the kdr of the stream.
Create a procedure that returns a promise to evaluate the body of the procedure. The last body expression to be evaluated must yield a stream.
As with normal lambda
, formals may be a single variable
name, in which case all the formal arguments are collected into a single
list, or a list of variable names, which may be null if there are no
arguments, proper if there are an exact number of arguments, or dotted
if a fixed number of arguments is to be followed by zero or more
arguments collected into a list.
body must contain at least one expression, and may contain internal definitions preceding any expressions to be evaluated.
Examples:
(define strm123 (stream-cons 1 (stream-cons 2 (stream-cons 3 stream-null)))) (stream-car strm123) ⇒ 1 (stream-car (stream-cdr strm123)) ⇒ 2 (stream-pair? (stream-cdr (stream-cons (/ 1 0) stream-null))) ⇒ #f (stream? (list 1 2 3)) ⇒ #f (define iter (stream-lambda (f x) (stream-cons x (iter f (f x))))) (define nats (iter (lambda (x) (+ x 1)) 0)) (stream-car (stream-cdr nats)) ⇒ 1 (define stream-add (stream-lambda (s1 s2) (stream-cons (+ (stream-car s1) (stream-car s2)) (stream-add (stream-cdr s1) (stream-cdr s2))))) (define evens (stream-add nats nats)) (stream-car evens) ⇒ 0 (stream-car (stream-cdr evens)) ⇒ 2 (stream-car (stream-cdr (stream-cdr evens))) ⇒ 4
Next: streams cons, Up: streams [Index]