The query system uses a few stream operations that were not presented in chapter 3.
Stream-append-delayed and interleave-delayed are just like streamappend and interleave (section ), except that they take a delayed argument (like the integral procedure in section ). This postpones looping in some cases (see exercise ).
(define (stream-append-delayed s1 delayed-s2) (if (stream-null? s1) (force delayed-s2) (cons-stream (stream-car s1) (stream-append-delayed (stream-cdr s1) delayed-s2)))) (define (interleave-delayed s1 delayed-s2) (if (stream-null? s1) (force delayed-s2) (cons-stream (stream-car s1) (interleave-delayed (force delayed-s2) (delay (stream-cdr s1))))))
Stream-flatmap, which is used throughout the query evaluator to map a procedure over a stream of frames and combine the resulting streams of frames, is the stream analog of the flatmap procedure introduced for ordinary lists in section . Unlike ordinary flatmap, however, we accumulate the streams with an interleaving process, rather than simply appending them (see exercises and ).
(define (stream-flatmap proc s) (flatten-stream (stream-map proc s))) (define (flatten-stream stream) (if (stream-null? stream) the-empty-stream (interleave-delayed (stream-car stream) (delay (flatten-stream (stream-cdr stream))))))
The evaluator also uses the following simple procedure to generate a stream consisting of a single element:
(define (singleton-stream x) (cons-stream x the-empty-stream))