[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: stream-define

This page is part of the web mail archives of SRFI 40 from before July 7th, 2015. The new archives for SRFI 40 contain all messages, not just those from before July 7th, 2015.

On Tuesday, February 11, 2003 8:05 PM, Richard Kelsey [SMTP:kelsey@xxxxxxx] 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
              (delay (force
                  (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

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.