[racket-dev] racket/stream

From: Eli Barzilay (eli at barzilay.org)
Date: Sun Mar 27 12:36:21 EDT 2011

5 minutes ago, Matthew Flatt wrote:
> There's a naming-convention clash between
>  * `in-...' for sequences (sometimes streams) especially intended
>    for direct use in `for' forms, and
>  * operations on streams and sequences, which would normally start
>    `stream-' or `sequence-'.
> I see no problem with having both `in-sequences' and
> `sequence-append', for example, if it makes functionality easier to
> find.

It just sound like a bad idea.  One thing is that there's no
precedence for this that I know about, other than some multiple names
used for backward compatibility (which is not an issue here).  On the
other hand, there will always be confusing questions, on one side:

  I want to add a `foo', should I do it as a `sequence-foo' or as an

and on the user side there's a question of where should you look.

I would have said now that my guess is that the two things will
eventually diverge, with different functions on the two sides, and
small differences with the functions that are implemented in both
sides.  But guessing is not really needed, since it's already there:
how long would it take for someone to complain that there's no
`in-map'?  Or that there is a confusing difference between
`in-sequences' and `sequence-append'?

> I've fixed the implementation of `sequence-tail', `sequence-map',
> `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"

* Why not make it return a stream instead?  As it is, it makes for yet
  another representation of sequences, which would be avoided with
  that.  (The problem would be multiple values, but IMO the benefit of
  avoiding another representation is bigger.)

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

* 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?

> > * `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?

> > > The new `racket/stream' library provides stream versions of the
> > > functions, plus `stream-cons' (based on SRFI-41),
> > > `stream-empty?', `stream-first', and `stream-rest'.
> > 
> > Is there any reason that you've used the srfi code as-is? 
> I considered replacing it, but I left it alone because improving the
> implementation of lazy streams wasn't my immediate goal. Please feel
> free to improve it.


> > 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

          ((lambda (x) (x x)) (lambda (x) (x x)))          Eli Barzilay:
                    http://barzilay.org/                   Maze is Life!

Posted on the dev mailing list.