|
6 | 6 | * Status: **Implemented (Swift 5.5)**
|
7 | 7 | * Implementation: [apple/swift#35224](https://github.com/apple/swift/pull/35224)
|
8 | 8 | * Decision Notes: [Rationale](https://forums.swift.org/t/accepted-with-modification-se-0298-async-await-sequences/44231)
|
| 9 | +* Revision: Based on [forum discussion](https://forums.swift.org/t/pitch-clarify-end-of-iteration-behavior-for-asyncsequence/45548) |
9 | 10 |
|
10 | 11 | ## Introduction
|
11 | 12 |
|
@@ -194,12 +195,17 @@ If an `AsyncIteratorProtocol` type has cleanup to do upon cancellation, it can d
|
194 | 195 |
|
195 | 196 | 1. After checking for cancellation using the `Task` API.
|
196 | 197 | 2. In its `deinit` (if it is a class type).
|
| 198 | + |
197 | 199 | ### Rethrows
|
198 | 200 |
|
199 | 201 | This proposal will take advantage of a separate proposal to add specialized `rethrows` conformance in a protocol, pitched [here](https://forums.swift.org/t/pitch-rethrowing-protocol-conformances/42373). With the changes proposed there for `rethrows`, it will not be required to use `try` when iterating an `AsyncSequence` which does not itself throw.
|
200 | 202 |
|
201 | 203 | The `await` is always required because the definition of the protocol is that it is always asynchronous.
|
202 | 204 |
|
| 205 | +### End of Iteration |
| 206 | + |
| 207 | +After an `AsyncIteratorProtocol` types returns `nil` or throws an error from its `next()` method, all future calls to `next()` must return `nil`. This matches the behavior of `IteratorProtocol` types and is important, since calling an iterator's `next()` method is the only way to determine whether iteration has finished. |
| 208 | + |
203 | 209 | ## AsyncSequence Functions
|
204 | 210 |
|
205 | 211 | The existence of a standard `AsyncSequence` protocol allows us to write generic algorithms for any type that conforms to it. There are two categories of functions: those that return a single value (and are thus marked as `async`), and those that return a new `AsyncSequence` (and are not marked as `async` themselves).
|
@@ -287,6 +293,7 @@ For each of these functions, we first define a type which conforms with the `Asy
|
287 | 293 | ## Future Proposals
|
288 | 294 |
|
289 | 295 | The following topics are things we consider important and worth discussion in future proposals:
|
| 296 | + |
290 | 297 | ### Additional `AsyncSequence` functions
|
291 | 298 |
|
292 | 299 | We've aimed for parity with the most relevant `Sequence` functions. There may be others that are worth adding in a future proposal.
|
@@ -323,6 +330,7 @@ An earlier version of this proposal included an explicit `cancel` function. We r
|
323 | 330 | ### Asynchronous Cancellation
|
324 | 331 |
|
325 | 332 | If we used explicit cancellation, the `cancel()` function on the iterator could be marked as `async`. However, this means that the implicit cancellation done when leaving a `for/in` loop would require an implicit `await` -- something we think is probably too much to hide from the developer. Most cancellation behavior is going to be as simple as setting a flag to check later, so we leave it as a synchronous function and encourage adopters to make cancellation fast and non-blocking.
|
| 333 | + |
326 | 334 | ### Opaque Types
|
327 | 335 |
|
328 | 336 | Each `AsyncSequence`-to-`AsyncSequence` algorithm will define its own concrete type. We could attempt to hide these details behind a general purpose type eraser. We believe leaving the types exposed gives us (and the compiler) more optimization opportunities. A great future enhancement would be for the language to support `some AsyncSequence where Element=...`-style syntax, allowing hiding of concrete `AsyncSequence` types at API boundaries.
|
|
0 commit comments