-
Notifications
You must be signed in to change notification settings - Fork 3
Description
You sollicited feedback on this crate in rust-lang/rust#80094, but that did not seem like the right place to give it (off-topic wrt the original issue, which might eventually be closed if we all agree that array::zip is not the ideal solution to our problems), so let me give it here.
One think I really like about the general approach of this crate in that it focuses on safe interfaces first, which should be what users most often interact with. And the proposed interfaces look reasonable from the perspective of people using the iterator.
However, one thing I'm less sure about is that the abstraction is based on a struct that is constructed from a dynamic-sized iterator, rather than a trait in its own right like the Iterator trait, of which the current IteratorFixed struct would become the array::IntoIter special case.
I think that with this design, you may lose opportunities for optimizations where implementors of a prospective IteratorFixed trait could make use of the fact that most methods consume the entire iteration stream in order to specialize their code for this situation. These optimizations would only be lost if the IntoIterator bridge to dynamic-sized iteration were called, but not in the typical case where people want to eventually collect the results into a fixed-size collection.
Which leads me to this other point that in the current approach, third-party implementations of FromIteratorFixed for collections other than arrays (e.g. perfect hash maps) have no choice but to work by converting the iterator to a dynamic-sized iterator and unsafely assuming that this iterator has N items. Perhaps there is indeed no other way, but making every fixed-sized collection implementation require unsafe code feels like an undesirable outcome.
TL;DR: Unsafe conversion from dynamic-sized iterator and safe conversion into a dynamic-sized iterator that the caller must make unsafe assertions about seems like an imperfect core API to build upon, and it would be great if we could somehow come up with something better.
On an unrelated note, I also get the impression that some of the methods of the original Iterator that are currently excluded might actually exist, just in a runtime-checked + unsafe-unchecked form where the user asserts that the collection filter will yield M elements. This would not make sense for specialized filters (e.g. adding such an assertion would transform take_while(), into take()), but I could see a use case for general filters like filter() in situations where the user can assert that there will be M outputs, but cannot tell where these outpus lie in the data stream.