Skip to content
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

Amend RFC 2996 to replace Stream with AsyncIterator #3208

Merged
merged 2 commits into from
Dec 24, 2021

Conversation

yoshuawuyts
Copy link
Member

@yoshuawuyts yoshuawuyts commented Dec 14, 2021

RENDERED
Tracking Issue

This PR updates RFC 2996: Async Stream to use "async iterator" terminology instead. This was brought up on the async_stream tracking issue by @joshtriplett, capturing a conversation that happened on Zulip. The proposal has since seen quite a bit of support both from the ecosystem and async foundations working group.

Additionally there is also strong precedence in other languages for using an "iterator"/"async iterator" naming scheme:

Hence I'd like to propose this amendment to RFC 2996: Async Stream to use "async iterator" terminology instead. Thanks!


cc/ @rust-lang/libs-api, @rust-lang/wg-async-foundations @nellshamrell

@joshtriplett joshtriplett added the T-libs-api Relevant to the library API team, which will review and decide on the RFC. label Dec 14, 2021
@joshtriplett
Copy link
Member

This seems to reflect the API shift we've been talking about for a while and have been assuming would happen. Thanks for writing this up! I'm going to start an FCP to confirm consensus on this renaming.

@rfcbot merge

@rfcbot
Copy link
Collaborator

rfcbot commented Dec 14, 2021

Team member @joshtriplett has proposed to merge this. The next step is review by the rest of the tagged team members:

No concerns currently listed.

Once a majority of reviewers approve (and at most 2 approvals are outstanding), this will enter its final comment period. If you spot a major issue that hasn't been raised at any point in this process, please speak up!

See this document for info about what commands tagged team members can give me.

@rfcbot rfcbot added proposed-final-comment-period Currently awaiting signoff of all team members in order to enter the final comment period. disposition-merge This RFC is in PFCP or FCP with a disposition to merge it. labels Dec 14, 2021
@scottmcm
Copy link
Member

This does make sense to me; when I hear "stream" I think something different.

That said, should this add a section to the Rationale & Alternatives saying why this name was chosen?

@rfcbot rfcbot added final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. and removed proposed-final-comment-period Currently awaiting signoff of all team members in order to enter the final comment period. labels Dec 14, 2021
@rfcbot
Copy link
Collaborator

rfcbot commented Dec 14, 2021

🔔 This is now entering its final comment period, as per the review above. 🔔

@yoshuawuyts
Copy link
Member Author

That said, should this add a section to the Rationale & Alternatives saying why this name was chosen?

That's a good point. I think we should. Would it be okay if I file a follow-up PR so we can discuss the exact wording there without holding up the FCP in this PR?

@scottmcm
Copy link
Member

I think it's perfectly fine to add more "why" details during the FCP; they're not like bors where a new commit requires a new approval. (Changing the design can sometimes need a new FCP, but if it's just recording rationale and alternatives that doesn't invalidate checkboxes IMHO.)

So since it'll take 10 days for the FCP to complete anyway, I'd suggest just updating this PR. But later is totally fine too.

(And I'm not on libs-api, so nothing I say here is authoritative.)

@yoshuawuyts
Copy link
Member Author

So since it'll take 10 days for the FCP to complete anyway, I'd suggest just updating this PR. But later is totally fine too.

Ah, okay - I'll do that then!

@eholk
Copy link
Contributor

eholk commented Dec 14, 2021

This PR seems like a good change to me. While I like "Streams" better as a name (it's shorter and sounds better to my ears), it also conveys to me very little about what Streams actually are. I think AsyncIterator is much clearer in that it immediately gives some idea what it refers to, so it makes sense to prioritize clarity in my opinion.

Copy link
Member

@tmandry tmandry left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for putting this up, @yoshuawuyts.

This reflects the general approach we've been talking about for awhile to stick to AsyncFoo naming for any trait Foo which has a direct synchronous analogue in the standard library. While Stream is definitely nicer to type than AsyncIterator, I agree with @eholk that having clarity is important, and I think internal consistency and predictability are important too.

text/2996-async-iterator.md Outdated Show resolved Hide resolved
text/2996-async-iterator.md Outdated Show resolved Hide resolved
@yoshuawuyts
Copy link
Member Author

yoshuawuyts commented Dec 15, 2021

Added a section on naming, as requested.

text/2996-async-iterator.md Outdated Show resolved Hide resolved
@nikomatsakis
Copy link
Contributor

Big fan.

@workingjubilee
Copy link
Member

...Does this mean to say the iterator's elements are iterated over in a non-serial "out of order" fashion, so we are no longer required to iterate in a "eager" or "sync" fashion in order to execute an item, or that the iterator is iterated over serially, but the items returned are Futures?

@yoshuawuyts
Copy link
Member Author

@workingjubilee the iterator is iterated over serially, but the items returned are Futures. From the summary section of the RFC:

Async iterators are a core async abstraction. These behave similarly to Iterator, but rather than blocking between each item yield, it allows other tasks to run while it waits.

@Nemo157
Copy link
Member

Nemo157 commented Dec 22, 2021

...Does this mean to say the iterator's elements are iterated over in a non-serial "out of order" fashion, so we are no longer required to iterate in a "eager" or "sync" fashion in order to execute an item, or that the iterator is iterated over serially, but the items returned are Futures?

Those actually describe the same thing to my understanding, Iterator<Item = impl Future>, this would allow you to iterate over the items and wait for/compute them out-of-order since the futures are decoupled. AsyncIterator is different in that it serially but asynchronously waits for/computes the next item, you cannot skip over some items to a future item without waiting for those items to be computed and discarded (and there is another step in between this and the out-of-order version, StreamingIterator<Item<'a> = impl Future + 'a>, this allows you to skip items without waiting, but not resolve them out-of-order).

@tmandry
Copy link
Member

tmandry commented Dec 23, 2021

You must consume the items of an AsyncIterator serially (just like with Iterator); the Async only controls whether those items are produced synchronously or not. Similarly, the items can be produced out of order (with respect to some reference order), see e.g. FuturesUnordered which yields task results as they complete.

To restate what @Nemo157 said (partly for my own understanding): It's true that in both Iterator and AsyncIterator the item could be a Future which would allow you to poll them independently. Alternatively, you might want the hypothetical Streaming versions of each trait which would allow the yielded values to borrow from the iterator (or data it borrows from), but would prevent you from holding onto previously yielded items after you call next again.

I feel like there should be a table for all this :)

@workingjubilee
Copy link
Member

Yes, I think the "other interpretation" I had in mind was either StreamingIterator or FuturesUnordered, where there's even less rules on what is happening when, it's just everybody hitting the dance floor (but notionally, at least in my mind, there was still a "sequence that would be valid to iterate over").

StreamingIterator well and truly is a mouthful and also can break some intuitions about what "iteration" means, so I think I support this name change, if nothing else, to reserve Stream as a namespace for that.

@rfcbot rfcbot added finished-final-comment-period The final comment period is finished for this RFC. to-announce and removed final-comment-period Will be merged/postponed/closed in ~10 calendar days unless new substational objections are raised. labels Dec 24, 2021
@rfcbot
Copy link
Collaborator

rfcbot commented Dec 24, 2021

The final comment period, with a disposition to merge, as per the review above, is now complete.

As the automated representative of the governance process, I would like to thank the author for their work and everyone else who contributed.

This will be merged soon.

@joshtriplett joshtriplett merged commit c76963d into rust-lang:master Dec 24, 2021
@yoshuawuyts yoshuawuyts deleted the async-iterator branch December 31, 2021 10:09
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Feb 17, 2022
Move `{core,std}::stream::Stream` to `{core,std}::async_iter::AsyncIterator`

Following amendments in rust-lang/rfcs#3208.

cc rust-lang#79024
cc `@yoshuawuyts` `@joshtriplett`
matthiaskrgr added a commit to matthiaskrgr/rust that referenced this pull request Feb 18, 2022
Move `{core,std}::stream::Stream` to `{core,std}::async_iter::AsyncIterator`

Following amendments in rust-lang/rfcs#3208.

cc rust-lang#79024
cc ``@yoshuawuyts`` ``@joshtriplett``
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
disposition-merge This RFC is in PFCP or FCP with a disposition to merge it. finished-final-comment-period The final comment period is finished for this RFC. T-libs-api Relevant to the library API team, which will review and decide on the RFC. to-announce
Projects
None yet
Development

Successfully merging this pull request may close these issues.