Skip to content

Commit f4045ed

Browse files
authored
Revise AsyncSequence proposal to note end-of-iteration behavior (#1312)
1 parent 6e43647 commit f4045ed

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

proposals/0298-asyncsequence.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
* Status: **Implemented (Swift 5.5)**
77
* Implementation: [apple/swift#35224](https://github.com/apple/swift/pull/35224)
88
* 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)
910

1011
## Introduction
1112

@@ -194,12 +195,17 @@ If an `AsyncIteratorProtocol` type has cleanup to do upon cancellation, it can d
194195

195196
1. After checking for cancellation using the `Task` API.
196197
2. In its `deinit` (if it is a class type).
198+
197199
### Rethrows
198200

199201
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.
200202

201203
The `await` is always required because the definition of the protocol is that it is always asynchronous.
202204

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+
203209
## AsyncSequence Functions
204210

205211
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
287293
## Future Proposals
288294

289295
The following topics are things we consider important and worth discussion in future proposals:
296+
290297
### Additional `AsyncSequence` functions
291298

292299
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
323330
### Asynchronous Cancellation
324331

325332
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+
326334
### Opaque Types
327335

328336
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

Comments
 (0)