Make Peekable trait for Iterator

Hi, I would like to contribute to the following pre-rfc which has been closed due to inactivity: [Pre-RFC] Make Peekable trait for Iterator. The need came up on a personal project of mine. I had a struct with a custom implementation of the Iterator trait, but when I use .peekable(), the returned Peekable can't access any of the functions I implemented on my original structure. However, the pre-rfc has been closed for a few years now. How can I go about reopening it?

The usual way is to open a new thread with an updated proposal, or if no more design discussion is needed (unsure if this is the case here) you could start with an implementation PR.

However, I wonder whether this is the easiest way to address the need you encountered? Even if peekable() was made more generic in this way, using it for your purpose would still require you to write a custom type that combines the peeking capability with forwarding of your custom methods. You can already write this type today and use it in your code, it just won't be hooked up to Iterator::peekable. It seems unlikely that this matters in your case: even if you eventually pass the iterator to some generic (over I: Iterator) code that calls peekable() on the iterator, most likely it will consume the iterator and losing access to the other methods you added won't matter because that code doesn't know about them anyway.

It did matter in my case, interestingly. It was acting as a character buffer for an input file and I frequently used .take_while() to, for example, throw out whitespace, but that would also throw out the first non-whitespace character. I ended up using the Itertools crate which has the similar Peeking Next trait.

That's not totally relevant, though, I just thought it seems like an easy but useful thing I could contribute. I guess the question is whether more design discussion is needed. Who decides that? Since it's the whole reason I came across that, I think the trait should provide a .peeking_take_while() function.

You could add it as a PR on itertools. that seems to be where new iterator stuff is tested out. On rare occasions something from itertools gets added to std lib. I'm pretty sure it's an endorsed crate by the lang team, and having functionality in crates keeps the core language smaller.

Itertools already has multipeek functionality. What exactly would this add to that?

For my purpose, it would allow both peeking along with all the trait's provided functions as well as any other function that I've implemented. There were other possible uses given in the old thread, as well as in this GitHub issue which I forgot to link to (sorry), the most useful of which is that some structures in the standard library already "handle peek in an ad-hoc way, for example linked_list::IterMut::peek_next()." This trait would generalize that.

As an example of a use where this trait would be useful in the standard library as opposed to Itertools, the Chars iterator would be an excellent candidate to implement this trait. Every character is already stored in memory so peeking is zero-cost, and having it as a trait instead of wrapping the Chars iterator in a Peekable iterator will allow you to still call .as_str().

Not zero cost. Not expensive, but not zero cost. Peek would require doing UTF-8 decoding for the first character.

A peek for Chars specifically can already be done as chars.as_str().chars().first().

How is having it as a trait different from an inherent method? It's not like Peekable has any special functionality currently, anyway.

Well, an example of a provided method which couldn't be done easily with chars.as_str().chars().first() would be the .peeking_take_while() I mentioned above, which has the same functionality as .take_while() except it doesn't throw out the first item which fails the predicate.

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.