On Tuesday, February 11, 2003 8:05 PM, Richard Kelsey [SMTP:xxxxxx@s48.org] wrote:
> [ discussion of eliminating stream-define in favor of
> stream-delay, followed by discussion of eliminating
> unnecessary stream-defines in the reference
> implementation ]
I suppose your point is that the essence of a stream is
the delay/force mechanism, and my library offers no
easy access to just that mechanism by itself, only in
combination with lambda and variable binding. Thus
your stream-delay provides just that access and nothing
else, and can be used alongside lambda and define in
scheme expressions, just like any other data type. If I
understood that right, then it's fine with me to add
stream-delay, although I think I prefer the name
make-stream, for consistency with make-string and
make-vector, and because stream-delay emphasizes
the implementation mechanism rather than the data
type. (This means I will have to change the definition
of the :stream data type and several functions that
use it.)
There is also an intermediate step between
make-stream and stream-define. Stream-lambda
combines the delay/force stream mechanism with
function creation:
(define-syntax stream-lambda
(syntax-rules ()
((stream-lambda spec body0 body1 ...)
(lambda spec
(make-stream
(delay (force
(stream-promise
(let () body0 body1 ...)))))))))
I used "let ()" here, but this might be a case where
"begin" is more appropriate. Comments?
I left stream-lambda out of the SRFI because my
original mental model of stream functions was that
they would normally be defined recursively ("a stream
is an object followed by a stream"), but with
higher-order functions like stream-map and syntax
like stream-of that's not necessarily true, and a method
to create stream-valued functions belongs in the SRFI.
Thus I propose make-stream for the core and both
stream-lambda and stream-define for the derived
library.
Does all this make sense?
As to your other point, I may well have used
stream-define more often than necessary in the
reference implementation. I was responding to a
problem that shows up with this version of
stream-cons that was used in several preliminary
versions of the SRFI:
(define-syntax old-stream-cons
(syntax-rules ()
((old-stream-cons obj strm)
(if (not (stream? strm))
(stream-error "attempt to stream-cons onto non-stream object")
(make-stream (delay (cons obj strm)))))))
Given that definition, an expression like
(define ones (old-stream-cons 1 ones))
doesn't work, because the (stream? strm) unnecessarily
strictifies old-stream-cons. Delaying the error checks with
stream-define prevents the problem. Having said that, this
issue of premature strictification was my biggest hangup in
writing this SRFI, and I may have erred in going too far while
trying to prevent it.
Phil