010110__010110
In the first concrete installment of my series on iterator blocks I want to explore the possible feature set that could/should be supported in Rust. In the following paragraphs I will try to collect things that I think one would expect from iterator blocks in Rust. Mind, however, that this is just my opinion so far. I'd very much like to discuss this with anyone interested on the mailing list. Nevertheless, I think a collection like this is valuable as a point of departure—even if most of it won't make into a hypothetical final implementation.
I categorized the points below into must haves, nice to haves, and things to think about. The syntax I use here is very close to C# and should not be considered a proposal for the real syntax. This topic is big enough to warrant its own post.
yield
allows to implement
std::iterator::Iterator
trait in order to be compatible with the rest of the standard library and language facilities such as for
loops.
std::vec::ConsumeIterator
does).
Iterator blocks should be as fast as handwritten iterators if possible. In my view, this pretty much rules out any implementation relying on each iterator having its own stack. C#'s way of transforming the iterator block code into a lightweight state machine seems the way to go here.
It probably also means that iterators created from yielding functions should not require a heap allocation. That would mean that each iterator function should introduce its own type implementing std::iterator::Iterator
to allow for stack allocation and static method dispatch. This is just me thinking aloud, though. There has also been talk about other ways to deal with this problem.
for
loop). In this case, the error messages generated from the »de-sugared« version of the code might not be very helpful and even confusing.
yield break
from within an iterator block to end iteration explicitly. This more or less corresponds to a Rust Iterator
returning None
from next()
. One can probably get by without this, but it's definitely useful.
std::iterator
can be used there too). The state machine transformation should be able to fullfil this requirement.
next()
method in the `Iterator` trait would be able to take additional arguments:
The current Iterator
trait would then be a special case with T == ()
. This sounds kind of nice but I could not come up with a good use case. It also might complicate things unnecessarily. But I wanted to have mentioned it.