[racket-dev] racket/stream

From: Matthew Flatt (mflatt at cs.utah.edu)
Date: Mon Mar 28 08:49:47 EDT 2011

At Sun, 27 Mar 2011 12:36:21 -0400, Eli Barzilay wrote:
> > `sequence-filter', and `sequence-add-between'. The repair involved
> > adding `sequence-generate*', which starts a sequence in a way that
> > is consistent with using state but doesn't use state if the sequence
> > itself isn't stateful.
> * There are several typos in the documentation -- "like
>   `sequence-generate*'", and "list of values the ??? sequences's"

I've fixed those two. Others?

> * Why not make it return a stream instead?

Not all sequences are streams, and `sequence-generate*' is intended to
expose the (potentially non-stream) behavior of the sequence.

> * Also, I think that it's better to have an indicative name rather
>   than add a `*'.

Suggestions are welcome.

> * And a loosely related side question: would you have an objection to
>   changing the primitive sequence representation to something more
>   convenient than the thunk-returning-multiple-values thing?

An extra sequence constructor with a simpler API sounds fine, but I
don't know what you mean about changing the primitive sequence
representation. That is, I don't see how to represent sequences
differently without losing functionality or performance.

> > > * `sequence-add-between'
> > >     Should turn to `in-add-between', but that seems like an
> > >     arbitrary function from `racket/list' that is used in the
> > >     sequence interface.
> > 
> > Left in, on the grounds of history and that it seems plausibly useful.
> What would be the way to judge whether any of the other names in
> `racket/list' should be added too?

Whether someone is willing to implement them.

> > > But actually for ranges I prefer using a state-based produce in
> > > some form, since it's much faster.
> > 
> > I see how a state-based range can be faster if everything is
> > state-based, but I see no performance benefit for a range producer
> > that plugs into a more general stream/sequence protocol. Meanwhile,
> > using state has the obvious drawbacks (e.g., interacts badly with
> > continuations). Note that in revising `racket/sequence', I removed
> > all state (i.e., no state in any of the functions, except for any
> > state within a given sequence).
> What I was thinking of is something like making ranges a value that
> has both a stream form and a producer form, so when it's iterated on
> in a for loop, the side-effect version gets used.  Does this sound
> reasonable?

No. Either I don't understand or I haven't been clear on what I mean by
avoiding state in the traversal of sequences. I'll try to be clearer on
the avoiding-state part:


 (for ([i (in-range 100)])

the body of the `for' loop has to perform some side effect for the
`for' form to be useful, but the side effect may be I/O or some control
effect. If the body captures a continuation when `i' is 17, then
applying the continuation should resume the iteration so that `i'
advances to 18, even if the `for' loop had previously iterated `i' all
the way to 100.

A similar pattern of catching and resuming a continuation wouldn't work
as well with an input port as a sequence, since the sequence itself has
state. But we shouldn't hobble `for' in general just because it might
be used with stateful sequences.

Posted on the dev mailing list.