Stream API

That also came up during the discussion on post-nil behaviour:

So my point is that it sure seems like Iterators were designed to be single-pass.

The pitch mentioned a Stream API for single pass sequences. I remain convinced, as I wrote in the pitch, that allowing Collection to be infinite is the right thing to do, and that the time for introducing a protocol for single pass sequences will come only after we have move-only/non-copyable types in the language.

5 Likes

I don't think this is a bug, it is a consequence of implementing the iterator with a struct and hence the iterator gets copied, inside reduce. If you change it to a let you can still call reduce, though not next. reduce is non-mutating and it makes a copy of the iterator into a var and then uses that. This is the behaviour I don't like and wanted a truely single-pass Stream and hence the use of a class.

As an aside: you can't make reduce mutating since then it.filter { ... }.reduce(0, +) would fail because the temporary that the compiler makes for the output of filter is a let.

As I mentioned in the comments and as @dabrahams has mentioned in this forum it might be possible to use structs once we can have move semantics for structs.

Do you have a sketch of what Stream using structs with move semantics might look like.

It might be as simple as a non-copyable instance of IteratorProtocol.

2 Likes

Whilst single traversal is solved with move the other two issues I have are:

  1. Any part of chain can terminate. EG an iterative solution that converges, termination is only known part way down the chain.
  2. Cannot pass errors along the chain and terminate the iteration on error.