[racket-dev] racket/stream

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Wed Mar 16 17:06:56 EDT 2011

At Wed, 16 Mar 2011 13:21:28 -0400, Eli Barzilay wrote:
> >    Generators include the result of `generator' and input
> >    ports. (The `generator?' predicate currently returns false for
> >    input ports, but that could change.)
> 
> I'd rather see these generators be only thunks (explained below) -- so
> all thunks can be used as generators.  Possibly, "generator" becomes
> just a name for a thunk used to retreive values, usually based on some
> state -- but since this is confusing, I'll use "producer" here.

I see your point about "generator", and so I agree that we should use a
different term. I'm not too happy with the term "producer", but I don't
yet have a better suggestion.

> Using producer thunks looks to me better than generators (in the
> `racket/generator' sense) because some of them are not things that you
> could iterate over straightforwardly -- for example,
> 
>   (generator () (yield (yield 1)))
> 
> will expect a value on the second call (or with an input value, after
> your commit today, the first will require a value too).  It also looks
> to me better than an input port, which naturally resolves the question
> of how to read from the port -- you just turn it into a producer with
> 
>   (lambda () (some-read in))

I don't think that 0-arity procedures should be the only implementation
of producers. For example, it could be useful for the result of
`in-producer' to identify itself as a stateful sequence.


> > Based on the above terminology, here's the programming part of the
> > proposal:
> > 
> >  1. Rename `racket/stream' and its bindings back to "sequence".
> > 
> >  2. Introduce a `racket/stream' library that provides stream
> >     versions (typically lazy) of the current operations, including
> >     the expected lazy `stream-cons' form.
> 
> So what we talked about is similar, except that #2 replaces
> `racket/stream' in place.  `racket/sequence' doesn't happen since
> there's no point in that (and AFAICT, people really want the stream
> operations, not the sequence ones).

I'm not convinced that `racket/sequence' is useless. Here's a list of
the current functions (with the current names):

 empty-stream
 stream->list
 stream-cons
 stream-first
 stream-rest
 stream-length
 stream-ref
 stream-tail
 stream-append
 stream-map
 stream-andmap
 stream-ormap
 stream-for-each
 stream-fold
 stream-filter
 stream-add-between
 stream-count

Most functions, such as `stream-map', are just function forms of `for'
variants, but it seems useful and appropriate for a library to provide
those pre-made combinations. Functions like `sequence-tail' also seem
useful, even if the implementation isn't as straightforward as for
non-stream sequences.



Posted on the dev mailing list.