One thing I'd like to draw to attention is that I think we're going to need to perform some fairly major surgery on these types soon in order for them to support non-copyable (and non-escaping) element types.
Fundamentally, next()
cannot return an element; it needs to allow its caller to borrow an element.
In the language we have, you'd express this using a closure (rough example for illustration purposes):
protocol AsyncIteratorProtocol {
associatedtype Element: Sendable
associatedtype Failure: Error
mutating func next<T>(
_ yield: (Element) async throws(T) -> IterationResult
) async throws(errorUnion(Failure, T))
/* + isolation parameter in above */
}
enum IterationResult {
case continue
case break
}
And then you'd write your iterator like so:
mutating func next<T>(
_ yield: ([UInt8]) async throws(T) -> IterationResult
) async throws(errorUnion(Failure, T)) {
var buffer = [UInt8]()
while await populateBuffer(&buffer) {
guard try await yield(buffer) == .continue else { break }
}
}
And now that we're yielding borrows of the element rather than returning copies of it, the element can instead be a non-copyable type -- and even a non-escaping type like some kind of stack buffer.
Ultimately I'm sure we're going to want a real coroutine/generator interface in the language rather than literally adding an enum and asking people to write closure parameters everywhere, but this demonstrates the concept.
Noncopyable types have already shipped, there is a pitch and early implementation for using them in generics, and I've seen early implementation work for non-escaping types start to land in the compiler. So this doesn't seem to me like a distant fantasy any more; it might actually be a realistic thing that happens in the near future.
And so if we're going to have to do this sort of major surgery soon anyway (e.g. possibly outright deprecating AsyncIteratorProtocol
in favour of a generator interface), I wonder if it's really worth going through all of this now.
Can anybody illuminate the plans for supporting non-copyable and non-escaping types in async streams?