-
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
FusedIterator
marker trait and iter::Fuse
specialization
#1581
Conversation
Should this discuss the consequences of an iterator implementing this trait without meeting its requirements? I don't know if it's necessary to make this an See also #1051. |
@apasel422, are you worried that someone might be relying on the behavior of |
@Stebalien I'm not sure how it would happen in practice either, just pointing out some previous discussions around this matter. |
This RFC adds a `FusedIterator` marker trait and specializes `iter::Fuse` to do nothing when the underlying iterator already provides the `Fuse` guarantee.
@apasel422 I've added it to the unresolved questions (it's a very good question and, unfortunately, one I can't answer). Maybe if you eagerly freed or truncated something immediately after the iterator returned |
noticeable overhead. Furthermore, many iterators (most if not all iterators in | ||
std) already act as if they were fused (this is considered to be the "polite" | ||
behavior). Therefore, it would be nice to be able to pay the `Fused` overhead | ||
iff necessary. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/iff necessary/if possible/.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, I meant "if and only if necessary". Did you read an extra "not" into that sentence?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Did you read an extra "not" into that sentence?
Oh, I indeed did.
That being said, iff
is equivalent to logic-↔ and
“nice to be able to pay the Fused
overhead” → “necessary” ∧
“necessary” → “nice to be able to pay the Fused
overhead”
doesn’t really look right to me. /me shrugs.
EDIT: I propose “only when necessary” as replacement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure. FYI, when writing that sentence, I didn't mean to include the "nice to be able to" in the iff. That is, I meant "pay the overhead" → "necessary to pay the overhead" ∧ "necessary to pay the overhead" -> "pay the overhead". However, I guess the second part is implied.
I feel like we could just specialise exact cases we already know to be fused (that wouldn’t even need an RFC!). The only benefit of |
The RFC hides quite a bit of code. You'd have to repeat all this each time you wanted to specialize. This also prevents programmers from specializing |
I think we will have some iterator traits with much stronger "regularity" guarantees than this, maybe something like |
@nagisa a more general approach is to make it possible to specialize all iterator adapters (added to the RFC). Unfortunately, this has some drawbacks (also added to the RFC). |
Does specialization as it exists today provide any way to omit the flag on |
Yes. See rust-lang/rust#32999 (comment). Unfortunately, it's significantly more complicated and requires specializing associated types. |
🔔 This RFC is now entering its week-long final comment period 🔔 The libs team is leaning towards merging this as it provides a clear with for already-fused iterators and also allows the same benefits externally. Seems like a win win! |
@alexcrichton would you like me to squash? |
@Stebalien nah leaving all the commits as-is is fine, we actually prefer on RFCs to not squash! |
I just came here via TWiR, sorry to be late to the party. +1 for the idea, but I think the name is a bit unfortunate. It might be confusing to people who know about stream fusion, because “fusion” is used here in a similar context but with a totally different meaning. (Paper that uses the term too.) I’ve seen the term ”subject to fusion” used in Haskell documentation, but the It is probably too late to change this now, as |
@Stebalien Is the interface the same for both approaches? That is could we start with the simpler implementation and transition to the more complex but slightly more efficient one later? |
Yes. |
Discussed at libs triage the other day, the decision was to merge Thanks again for the RFC @Stebalien! |
I''ll revive the old PR ASAP but it might that might not be till September (impending thesis deadline). |
Implement 1581 (FusedIterator) * [ ] Implement on patterns. See #27721 (comment). * [ ] Handle OS Iterators. A bunch of iterators (`Args`, `Env`, etc.) in libstd wrap platform specific iterators. The current ones all appear to be well-behaved but can we assume that future ones will be? * [ ] Does someone want to audit this? On first glance, all of the iterators on which I implemented `FusedIterator` appear to be well-behaved but there are a *lot* of them so a second pair of eyes would be nice. * I haven't touched rustc internal iterators (or the internal rand) because rustc doesn't actually call `fuse()`. * `FusedIterator` can't be implemented on `std::io::{Bytes, Chars}`. Closes: #35602 (Tracking Issue) Implements: rust-lang/rfcs#1581
Implement 1581 (FusedIterator) * [ ] Implement on patterns. See rust-lang/rust#27721 (comment). * [ ] Handle OS Iterators. A bunch of iterators (`Args`, `Env`, etc.) in libstd wrap platform specific iterators. The current ones all appear to be well-behaved but can we assume that future ones will be? * [ ] Does someone want to audit this? On first glance, all of the iterators on which I implemented `FusedIterator` appear to be well-behaved but there are a *lot* of them so a second pair of eyes would be nice. * I haven't touched rustc internal iterators (or the internal rand) because rustc doesn't actually call `fuse()`. * `FusedIterator` can't be implemented on `std::io::{Bytes, Chars}`. Closes: #35602 (Tracking Issue) Implements: rust-lang/rfcs#1581
This RFC adds a
FusedIterator
marker trait and specializesiter::Fuse
to donothing when the underlying iterator already provides the
Fuse
guarantee.See this discussion for context.
rendered
WIP PR
/cc @bluss, @gankro