SE-0421: Generalize effect polymorphism for AsyncSequence and AsyncIteratorProtocol

Hello Swift community,

The review of SE-0421: Generalize effect polymorphism for AsyncSequence and AsyncIteratorProtocol begins now and runs through February 7, 2024.

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to me as the review manager via the forum messaging feature. When contacting the review manager directly, please put "SE-0421" in the subject line.

Trying it out

If you'd like to try this proposal out, you can download a toolchain supporting it:

What goes into a review?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift. When writing your review, here are some questions you might want to answer in your review:

  • What is your evaluation of the proposal?
  • Is the problem being addressed significant enough to warrant a change to Swift?
  • Does this proposal fit well with the feel and direction of Swift?
  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

More information about the Swift evolution process is available at

https://github.com/apple/swift-evolution/blob/main/process.md

Thank you,

Freddy Kellison-Linn
Review Manager

13 Likes

As AsyncIteratorProtocol and AsyncSequence are declared in _Concurrency couldn't we use BackDeploymentConcurrency on OSes with runtime up to 5.11 and thus get rid of the @available ?

Sounds great.

Thinking ahead a bit, what will happen for an AsyncStream conformer that implements back-pressure? i.e. doesn't necessarily sit waiting in the upstream next all the time; how will it support cancellation if it can no longer throw CancellationError (because the type is no longer necessarily the unlimited any Error)? Is it forced to just quietly return nil from its iterator's next?

Definitely +1 on this proposal. This will resolve a longstanding issue with AsyncSequence and finally make it more usable. One thing I wonder is with this proposal, what is the future of @rethrows protocols? They were never officially put through Evolution, but they exist in the language today. Should we deprecate or remove them?

2 Likes
  • What is your evaluation of the proposal?

+1. This proposal solves two of the existing problems with the AsyncSequence protocol in a pragmatic way.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes this problem is very important to address and has made usage of AsyncSequences hard or impossible without introducing Sendable problems.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I reviewed the proposal in-depth and worked extensively with AsyncSequences in the past.

AsyncStream and AsyncThrowingStream are currently both returning nil when they recognise that their consuming task was cancelled.

A bit of topic, but would it be worth it to create another proposal to allow the AsyncStream / AsyncThrowingStream to specify the cancellation behavior, e.g. by adding to the init:

init(
    _ elementType: Element.Type = Element.self,
    bufferingPolicy limit: AsyncStream<Element>.Continuation.BufferingPolicy = .unbounded,
    cancellationStrategy: CancellationStrategy = .immediate,
    _ build: (AsyncStream<Element>.Continuation) -> Void
)

public enum CancellationStrategy {
    case immediate
    case cooperative
}

Yes, we should deprecate and remove them. Assuming this proposal (or something similar to it) goes through to obviate the need for @rethrows, we'll start staging them out soon.

Doug

4 Likes

+1, great addition!

For completeness, I'd like to note in this thread that SE-0421 has been accepted. Thank you all for your feedback!

4 Likes