-
Notifications
You must be signed in to change notification settings - Fork 1.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Replace IteratorExt::zip with tuple iteration #870
Conversation
Is this not a bit of a regression since you can theoretically indefinitely Zip, whereas with this you'll run into Tuple impl size limits quickly? Otherwise my only objection to this is the vague "Rust is becoming more magic" problem (that I am incredibly guilty of exacerbating). But maybe this is more intuitive that there being a method called Zip? |
If that would help my case for this RFC, I could collect a list of cries for help on stackoverflow of people trying to zip in several languages without knowing the keyword zip. |
👎 I'll agree that I prefer to use a function named Also your comment above:
Doesn't really jive with your statement in the forum:
|
@gankro regarding the regression, I'm not sure I follow. Isn't todays zip just equivalent to a 2-tuple here? In particular, can't you nest tuples to achieve arbitrary iteration? for (x, (y, z)) in (xs, (ys, zs)) { ... } Or am I missing something? |
(I do think that as far as "guessability" goes, zip is probably more guessable than tuples, since it is used in so many languages.) |
I have mixed feelings. I feel like this approach is beautifully concise, but it may be a learning hazard. On the other hand, that's true for a lot of iterator magic (e.g., collecting into a (That said, for some reason now that |
Perhaps I would like to have |
@nikomatsakis. Ah yes, you're right. Didn't occur to me that that would "just work". |
i could live with |
What if someone implements IntoIter for arbitrary same-size tuples? I think it would not necessariily be ambiguous (because of the match on (x, y, z)), but it could throw off fellow developers who may be unsure what the code is doing. |
@llogiq: i guess that's similar to someone implementing IntoIter for [T] or something. The compiler would tell you this exists already. |
I think, bad searchability is a relatively weak argument against this proposal. |
Could this be done with polymorphic impls, or does it need to hefty syntactic support? |
@Ericson2314 well we need some macro magic for tuples with 1 to n elements. n probably being something around 10 |
I would have assumed this would work: impl<I: IntoIter, J: IntoIter> impl IntoIter for (I, J) {
type IntoIter= (<I as IntoIter>::IntoIter, <J as IntoIter>::IntoIter);
...
}
impl<I: Iter, J: Iter> impl Iter for (I, J) {
type Item = (<I as IntoIter>::Item, <J as IntoIter>::Item);
...
} and so on for larger tuples. |
yes, that will be generated by macros, as to not repeat ourselves. I have a sample implementation in the rfc. it's rather blunt, but if the rfc is accepted i will actually put in an effort to make it nice |
Ok, just checking. I thought people were implying the feature itself would require compiler syntactic support, when really it's just that its implementation would benefit from it, but doesn't even need it. I'm more for this then. Sure its a bit spooky but isn't proposing anything that couldn't be done already (baring coherence). |
I've come around to this. Let's lean into the magic together, everyone |
Cool consequence when extend is upgraded to use IntoIterator:
|
I added another alternative: requiring |
Ah...this is gorgeous! It's so obvious that I'm surprised it hasn't been brought up sooner. |
👍 This is amazing and I want it. |
This is cute. I agree fully with @nikomatsakis though. I feel pretty hesitant about this. |
Looks nice but I think this should be solved in a more structural way instead of applying magic. |
I like how intuitive this notation is. How do you iterate through a list of elements?
How do you iterate through two lists simultaneously?
, but with some parentheses required. |
While this is a clever idea with some promise, it is also very much a nice-to-have, and I'm strongly inclined to exercise discretion in adding new features to Rust at this time. I've opened #930 to let this idea continue to bake, but am closing this PR. Thank you. |
This makes it a little easier to `zip` iterators: ```rust for (x, y) in (xs, ys) {} // vs. for (x, y) in xs.into_iter().zip(ys) {} ``` You can iterate `(&mut xs, &ys)` for the conventional `iter_mut()` and `iter()`, respectively. This can also support arbitrary nesting, where it's easier to see the item layout than with arbitrary `zip` chains: ```rust for ((x, y), z) in ((xs, ys), zs) {} for (x, (y, z)) in (xs, (ys, zs)) {} // vs. for ((x, y), z) in xs.into_iter().zip(ys).zip(xz) {} for (x, (y, z)) in xs.into_iter().zip((ys.into_iter().zip(xz)) {} ``` Only tuple pairs are implemented for now. It's possible to implement longer tuples, but that would require a new iterator type to produce those tuple items. See itertools' [`Zip`] and rayon's [`MultiZip`] for prior art there. [`Zip`]: https://docs.rs/itertools/0.9.0/itertools/structs/struct.Zip.html [`MultiZip`]: https://docs.rs/rayon/1.4.1/rayon/iter/struct.MultiZip.html See also rust-lang/rfcs#870 and rust-lang/rfcs#930.
Should iterate over
a
,b
andc
(if all of them implementIntoIterator
) and return the current element of each of them inx
,y
, andz
until any ofa
,b
orc
return None.internals.rust-lang.org discussion
Rendered