[racket-dev] racket/stream
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:
In
(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.