I feel like this is a miss for a few reasons:
- It's a really clunky protocol; it'd be a shame for this to be "the way to write sequences".
Sequenceis pretty easy. Rust'sIteratoris easier in most circumstances. This is worse. - It seems to be "too soon" — it doesn't handle nonescaping elements, and doesn't seem like it'll be extensible to nonescaping elements in the future, given that they require lifetime annotations. I don't think nonescaping elements are an edge-case or uncommon need. So won't we just be back here in 6-12 months when lifetimes have caught up, trying to specify
BorrowingNonescapingSequence? - It seems to be "too soon" — implementing it requires using the
Lifetimesexperimental feature. This was promised to be stable, but broke source-compatibility between 6.2 and 6.3 already. I don't trust that implementations ofBorrowingSequencemade for 6.4 will compile in 6.5. - I don't like that this isn't "replacing"
Sequence, since there are cases thatSequencesupports butBorrowingSequencedoes not. I'd like to see more discussion of whether there is a design that allows for a true one-size-fits-all?
Thoughts about a more one-size-fits-all solution:
Are we just ignoring Rust's prior art here? In Rust:
Iteratorcan be over values or borrows, and might or might not itself be escaping depending on which one.- There's only standardization on how to get a consuming iterator from a container. This means that for loops can be less ergonomic (
for item in containerconsumes the container,for item in container.iter()is an ad-hoc standard to get a borrowing iterator, but it allows for other options likefor item in container.drain(3..14)to get an iterator that consumes items in a specified range of aVec, for example.
So what if,
- We adjust
IteratorProtocolto allow nonescaping implementors & nonescapingElement - The compiler's
forsyntax gets special support forIteratorProtocol<T>(current),IteratorProtocol<Borrow<T>>(new) andIteratorProtocol<Span<T>>(new):- When iterating sequences of
Borrow, the iteration variable is implicitly shorthand forborrow.value(so you don't have to manually deref the borrow on each use within the loop) - When iterating sequences of
Span, the iteration variable is implicitly shorthand forspan[i]. This is more or less equivalent toBorrowingIteratorProtocolfrom the current proposal.
- When iterating sequences of
Sequenceremains shorthand for "i can get a copying, escapable iterator"- We create an ad-hoc standard for getting a borrowing iterator, eg.
for element in container.borrow(). I suggest this because it avoids ambiguity over "which kind of iterator is this for loop using" compared to having bothSequenceandBorrowingSequence, and also makes it clear that offering other kinds of iterator through other ad-hoc methods is reasonable (see drain)