# \[Pitch\] Generalize \`AsyncSequence\` and \`AsyncIteratorProtocol\`

**URL:** <https://forums.swift.org/t/pitch-generalize-asyncsequence-and-asynciteratorprotocol/69283>\
**Category:** Pitches\
**Tags:** concurrency, asyncsequence\
**Created:** [January 5, 2024, 4:13am UTC](https://forums.swift.org/t/pitch-generalize-asyncsequence-and-asynciteratorprotocol/69283 "2024-01-05T04:13:35Z")\
**Posts on this page:** 1\
**Showing post:** 4

<div class="post-metadata">

**Author:** ![FranzBusch](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/franzbusch/32/19447_2.png) [@FranzBusch](https://forums.swift.org/u/FranzBusch)\
**Post date:** [January 5, 2024, 3:34pm UTC](https://forums.swift.org/t/pitch-generalize-asyncsequence-and-asynciteratorprotocol/69283/4 "2024-01-05T15:34:44Z")

</div>

Thanks for taking this part of the [Typed throws in the Concurrency module pitch](https://forums.swift.org/t/pitch-typed-throws-in-the-concurrency-module/68210). This is definitely one of the more complicated pieces of the pitch and I agree that having a dedicated pitch for it is very sensible.

Now to some feedback on the pitch.

```swift
mutating func nextElement(_ actor: isolated (any Actor)?) async throws(Failure) -> Element?

```

This is the first method where we are adopting the isolated parameter in the standard library if I am not mistaken. I don't think we have written any API design guidelines around the naming of `isolated` parameters and I find the proposed call site spelling a bit confusing:

```swift
var iterator: some AsyncIteratorProtocol<Int, Never> = ...
let element = await iterator.nextElement(nil)

```

Just from looking at the code it isn't obvious what `nil` means here. Similarly if I would be passing `self` if I am inside an actor. What if we add an external parameter label here e.g. `nextElement(isolatedTo actor: ...)`?

> To avoid silently allowing conformances that implement neither requirement, and to facilitate the transition of conformances from `next()` to `nextElement()` , we add a new availability rule where the witness checker diagnoses a protocol conformance that uses an deprecated, obsoleted, or unavailable default witness implementation. Deprecated implementations will produce a warning, while obsoleted and unavailable implementations will produce an error.

This is really cool and something that makes evolving protocols forward with minimal adopter friction amazing! @ktoso maybe we can use this trick for the `SerialExecutor` protocols as well once it landed.

> Once the concrete `AsyncIteratorProtocol` types in the standard library, such as `Async{Throwing}Stream.Iterator` , implement `nextElement()` directly, code that iterates over those concrete `AsyncSequence` types in an actor-isolated context may exhibit fewer hops to the generic executor at runtime.

This is quite an important part of the pitch that has a larger impacted then just fewer hops and IMO deserves a bit more discussion. With [SE-0306](https://github.com/apple/swift-evolution/blob/main/proposals/0338-clarify-execution-non-actor-async.md) we have changed the execution semantics of non isolated methods to eagerly hop to the global concurrent executor since we noticed that users of Swift Concurrency were often hogging the `MainActor` with non-isolated methods. With this pitch we introduce the first method in the standard library where we aggressively try to stick to the current context's isolation; hence, we introduce a new area where developers might hog the `MainActor`.  
Personally, I don't think this is a bad thing but it might result in performance changes for applications once they recompile with a newer Swift version and the `nextElement(_:)` implementation gets picked by the compiler.

> Note that the use of an existential type `(any Actor)?` means that [embedded Swift](https://github.com/hborla/swift-evolution/blob/generalize-async-sequence/visions/embedded-swift.md) would need to support class existentials in order to use `nextElement()` .

Do we think this is a reasonable thing for Embedded Swift to support in the future? It would be sad if we would limit the possible usage of `AsyncSequence` for Embedded because of the usage of `any Actor` here.

Lastly, the original pitch of @ktoso and me included changes to the various async sequence algorithms in the standard library. Do we foresee any problems if we are only landing the protocol/compiler changes for typed throws but not adopt them in the algorithms?

---

_[View the full topic](https://forums.swift.org/t/pitch-generalize-asyncsequence-and-asynciteratorprotocol/69283)._
