[Accepted] Amendment to SE-0296: Allow overloads that differ only in async

Hello Swift Community,

The review of an amendment to SE-0296 "async/await" ran from June 21...28, 2021. The amendment is accepted.

It was generally accepted that overloading on async would be beneficial. Most of the discussion centered not on async, but on throws. Accepting this amendment makes async more different from throws, and there was some sentiment that this amendment should only be accepted if we also allow overloading on throws accordingly. The Core Team disagreed with this approach for two specific reasons:

  • First, throws is not necessarily as amenable to overloading as async, due to the presence of control flow that handles thrown errors without requiring the enclosing context to be throws (try?, try!, and do..catch constructs have no analogy in async). It is not a given that throws and async must be consistent with respect to their overloading behavior.
  • Second, overloading on async is timely in a way that throws is not. There are no async APIs now, but the Swift community will be adding them as soon as Swift 5.5 becomes available. Without overloading on async, the Swift ecosystem will end up with a nontrivial number of APIs with non-ideal names (e.g., an Async suffix) that won't be able to be fixed later. throws is different, because the overloading rule has been in place since Swift 2.0. Delaying the ability to overload on async has long-term costs that the Core Team feels are not justified by the potential for inconsistency.

The Core Team is amenable to considering a proposal for overloading on throws, separately from this amendment. Part of the motivation for such a proposal can be consistency with async. However, such a proposal should account for the differences in semantics, and also consider the source-compatibility ramifications of making such a change.

Thank you to everyone who participated in the review!

Doug Gregor
Review Manager