This page is part of the web mail archives of SRFI 40 from before July 7th, 2015. The new archives for SRFI 40 are here. Eventually, the entire history will be moved there, including any new messages.
I think you should replace STREAM-DEFINE with a non-DEFINE version. In introducing STREAM-DEFINE the SRFI says: ... with the (delay (force ...)) hidden within stream-define, which is the syntax used to create a function that returns a stream: The problem is that STREAM-DEFINE is syntax used to define a function that returns a stream, not just to create such a function. What about the LAMBDA's that are not the value in a DEFINE? Not to mention those benighted individuals who don't like the (DEFINE (F ...) ...) syntax in the first place. You could replace STREAM-DEFINE with STREAM-DELAY: (define-syntax stream-delay (syntax-rules () ((stream-delay x) (make-stream (delay (force (stream-promise x))))))) Then (stream-define (foo a b) stuff) could be written as (define (foo a b) (stream-delay stuff)) which has the advantage of making it possible to control which expressions get delayed and which don't. But mostly, it makes it clearer what is going on. Unless I am missing something the code in the SRFI uses STREAM-DEFINE more often than necessary. Take MAP2 and COUNTDOWN2 from the initial explanation of even and odd streams: (define (map2 func strm) (delay (force (if (nil2? strm) nil2 (cons2 (func (car1 strm)) (map2 func (cdr2 strm))))))) (define (countdown2 n) (delay (force (cons2 n (countdown2 (- n 1)))))) The DELAY-FORCE in MAP2 is needed to delay the call to NIL2?. Without it MAP2 wouldn't return a fully-lazy stream. But the DELAY-FORCE in COUNTDOWN2 is only delaying a CONS2 expression, which expands into a DELAY. There is no utility in delaying the creation of a delay. The reference implementation itself uses STREAM-DEFINE in many places where DEFINE would work, including the definitions of STREAM-FROM, STREAM-FROM-TO, STREAM-REPEAT, and STREAM-ITERATE. Many of the functions that do need a delay would benefit from moving the delay after some initial error checks. For example, writing STREAM-UNIQ using STREAM-DELAY allows it to signal errors when it is called instead of waiting until the result is forced: (define (stream-uniq eql? strm) (if (not (procedure? eql?)) (stream-error "non-functional argument to uniq")) (if (not (stream? strm)) (stream-error "non-stream argument to uniq")) (stream-delay (if (stream-null? strm) stream-null (let ((first (stream-car strm))) (stream-cons first (stream-uniq-aux eql? strm first))))) -Richard Kelsey