Thinking about this a little more, is there perhaps a staged solution that would move things forward without needing to commit to a full typed throws proposal?
One part that seems that it could stand as a proposal in its own right is permitting the the throws
effects clause to include a thrown type. Even if, in the meantime, that thrown type is restricted to be either Never
or Error
.
Something equivalent to:
func f() throws(E) -> T // where E is Never or Error (until a full typed throws proposal...)
As I've seen discussed elsewhere, this would still allow the specification of functions without a specific type specified for E
, they would simply be resolved to the fully qualified signature, so that:
func f() throws -> T // equivalent to `func f() throws(Error) -> T`
And:
func f() -> T // equivalent to `func f() throws(Never) -> T`
With this in place a protocol like AsyncIteratorProtocol
could be rewritten as:
@rethrows public protocol AsyncIteratorProtocol {
associatedtype Element
associatedtype Failure: Error
mutating func next() async throws(Failure) -> Self.Element?
}
It seems that this would be a non-breaking change, as a non-throwing asynchronous iterator's next()
method would resolve to mutating func next() throws(Never) -> Element?
, and a throwing asynchronous iterator's next()
method would resolve to mutating func next() throws(Error) -> Element?
– so the new Failure
type could be inferred.
Then perhaps, if we could define a default parameter on a primary associated type, we could redefine AsyncSequence
as something like:
@rethrows public protocol AsyncSequence<Element, Failure=Never> {
associatedtype AsyncIterator: AsyncIteratorProtocol
associatedtype Element where Element == AsyncIterator.Element
associatedtype Failure where Failure == AsyncIterator.Failure
func makeAsyncIterator() -> Self.AsyncIterator
}
Which would finally allow for using AsyncSequence
as an opaque type:
func iterate(_ sequence: some AsyncSequence<T>) async
func iterateThrows(_ sequence: some AsyncSequence<T, Error>) async throws
That's a long way of saying, perhaps the function signature for typed throws stands on its own as a useful mechanism – even without a full typed throws proposal.