# SE-0296: async/await

**URL:** <https://forums.swift.org/t/se-0296-async-await/42605>\
**Category:** Proposal Reviews\
**Created:** [December 8, 2020, 6:23pm UTC](https://forums.swift.org/t/se-0296-async-await/42605 "2020-12-08T18:23:26Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![ben-cohen](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ben-cohen/32/296_2.png) [@ben-cohen](https://forums.swift.org/u/ben-cohen)\
**Post date:** [December 8, 2020, 6:23pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/1 "2020-12-08T18:23:26Z")

</div>

Hi Swift Evolution!

The review of [SE-0296 — `async`/`await`](https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md) begins now and runs through December 22, 2020.

Reviews are an important part of the Swift evolution process. All review feedback should be either on this forum thread or, if you would like to keep your feedback private, directly to the review manager (via [email](mailto:ben_cohen@apple.com) or direct message in the Swift forums).

## What goes into a review of a proposal?

The goal of the review process is to improve the proposal under review through constructive criticism and, eventually, determine the direction of Swift.

When reviewing a proposal, here are some questions to consider:

- What is your evaluation of the proposal?
- Is the problem being addressed significant enough to warrant a change to Swift?
- Does this proposal fit well with the feel and direction of Swift?
- If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?
- How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Thanks,  
Ben Cohen  
Review Manager

---

<div class="post-metadata">

**Author:** ![Dante-Broggi](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dante-broggi/32/7955_2.png) [@Dante-Broggi](https://forums.swift.org/u/Dante-Broggi)\
**Post date:** [December 8, 2020, 7:20pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/2 "2020-12-08T19:20:54Z")

</div>

Nit:

> [@](#):
>
> The positions of the new uses of `async` within the grammar (function declarations, function types, and **as a prefix for `let`** )

the bolded part (emphasis mine) is part of [structured-concurrency](https://github.com/DougGregor/swift-evolution/blob/structured-concurrency/proposals/nnnn-structured-concurrency.md), not this proposal, correct?

---

<div class="post-metadata">

**Author:** ![dabrahams](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dabrahams/32/9815_2.png) [@dabrahams](https://forums.swift.org/u/dabrahams)\
**Post date:** [December 8, 2020, 11:52pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/3 "2020-12-08T23:52:16Z")

</div>

FYI: It's not only about async/await, so I made a [separate post](https://forums.swift.org/t/on-the-proliferation-of-try-and-soon-await/42621), but I have raised several issues there that are particularly relevant here:

- What is the `await` keyword really _for_, and when does requiring it help protect the programmer? Are there kinds of code where it's just boilerplate?
- What will we do about the likely proliferation of needless `try`'s in async code?

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [December 9, 2020, 12:21am UTC](https://forums.swift.org/t/se-0296-async-await/42605/4 "2020-12-09T00:21:25Z")

</div>

> [@Dante-Broggi](#):
>
> Nit:
> 
> > [@](#):
> >
> > The positions of the new uses of `async` within the grammar (function declarations, function types, and **as a prefix for `let`** )
> 
> the bolded part (emphasis mine) is part of [structured-concurrency](https://github.com/DougGregor/swift-evolution/blob/structured-concurrency/proposals/nnnn-structured-concurrency.md), not this proposal, correct?

You are correct; fixed by [[SE-0296] 'async' is not a prefix for 'let' in this proposal. by DougGregor · Pull Request #1231 · apple/swift-evolution · GitHub](https://github.com/apple/swift-evolution/pull/1231). Thanks!

Doug

---

<div class="post-metadata">

**Author:** ![Douglas\_Gregor](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/douglas_gregor/32/1362_2.png) [@Douglas\_Gregor](https://forums.swift.org/u/Douglas_Gregor)\
**Post date:** [December 9, 2020, 12:36am UTC](https://forums.swift.org/t/se-0296-async-await/42605/5 "2020-12-09T00:36:14Z")

</div>

> [@dabrahams](#):
>
> What is the `await` keyword really _for_ , and when does requiring it help protect the programmer? Are there kinds of code where it's just boilerplate?

Definitionally, it indicates [potential suspension points](https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md#suspension-points). These are places where you may give up the thread of execution, which has various user-visible effects, including (1) the resumption might occur "much" later, which is both a potential performance concern as well as throwing off anything you're doing that might involve absolute times; (2) if you're accessing any state where suspension allows interleaving to occur, e.g., if interleaving is allowed for actors; (3) if you're using existing APIs that somehow depend on the actual OS thread you're using, e.g., because they are using thread-local storage.

> [@dabrahams](#):
>
> What will we do about the likely proliferation of needless `try` 's in async code?

You probably need to show examples of a "needless" `try`s introduced by async code. `async` doesn't require `throws`, which is why [`await` does not imply `try`](https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md#make-await-imply-try).

Doug

---

<div class="post-metadata">

**Author:** ![kavon](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/kavon/32/9774_2.png) [@kavon](https://forums.swift.org/u/kavon)\
**Post date:** [December 9, 2020, 12:51am UTC](https://forums.swift.org/t/se-0296-async-await/42605/6 "2020-12-09T00:51:59Z")

</div>

> [@dabrahams](#):
>
> What will we do about the likely proliferation of needless `try` 's in async code?

In existing async code, there's already a proliferation of `Result<T, Error>` when errors need to be propagated. Uses of Result are neatly replaced with the existing `try` mechanism in combination with the proposed async/await feature. You can get an early taste of the difference it makes in NetNewsWire (as an example) here: [Concurrency Upgrades by kavon · Pull Request #1 · kavon/NetNewsWire · GitHub](https://github.com/kavon/NetNewsWire/pull/1/files) (note that the changes are a work-in-progress)

---

<div class="post-metadata">

**Author:** ![dabrahams](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/dabrahams/32/9815_2.png) [@dabrahams](https://forums.swift.org/u/dabrahams)\
**Post date:** [December 9, 2020, 2:34am UTC](https://forums.swift.org/t/se-0296-async-await/42605/7 "2020-12-09T02:34:09Z")

</div>

Doug, thanks for your answer. I think it would be more useful to discuss this stuff in the thread I referenced, where there's more context, which is why I made it a separate thread. I was just trying to preview the issues here.

Thanks in particular for the response about `await`; I'll have to give what you said there some thought…

> [@Douglas\_Gregor](#):
>
> You probably need to show examples of a "needless" `try` s introduced by async code. `async` doesn't require `throws` , which is why [`await` does not imply `try`](https://github.com/apple/swift-evolution/blob/main/proposals/0296-async-await.md#make-await-imply-try).

I know it isn't implied by the proposed language definition. But as I wrote in the referenced post, the issue is that composable `async` code requires pervasive cancellability, which in our system means pervasive `try`… and nearly all instances of `try` are needless.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [December 9, 2020, 6:41am UTC](https://forums.swift.org/t/se-0296-async-await/42605/8 "2020-12-09T06:41:26Z")

</div>

The proposal includes these lines:

> Instead, think of an asynchronous function as an ordinary function that has the special power to give up its thread. Asynchronous functions don’t typically use this power directly; instead, they make calls, and sometimes these calls will require them to give up their thread and wait for something to happen. When that thing is complete, the function will resume executing again.

It says that an async function doesn’t _typically_ give up its thread directly. This implies that an async function _can_ give up its thread directly.

Is that capability in fact being proposed?

If so, what is the proposed spelling?

When an async function directly gives up its thread, how can it specify when to resume execution?

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [December 9, 2020, 4:29pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/9 "2020-12-09T16:29:18Z")

</div>

The proposal says:

> For example, if an asynchronous function is running within a given context that is protected by a serial queue, reaching a suspension point means that other code can be interleaved on that same serial queue.

Is this behavior being proposed?

If so, how can it be achieved?

As in, could we see an example (written in Swift using this proposal) of how to create a serial queue which can interleave code when something on it suspends?

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [December 9, 2020, 4:35pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/10 "2020-12-09T16:35:43Z")

</div>

> [@Nevin](#):
>
> Is this behavior being proposed?
> 
> If so, how can it be achieved?
> 
> As in, could we see an example (written in Swift using this proposal) of how to create a serial queue which can interleave code when something on it suspends?

My understanding is that it is not a part of this proposal. It maybe be possible to provide an example with this + the Structured Concurrency proposal, but not with plain `async`/`await`. Structured concurrency API would give you a way to schedule tasks on queues etc.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [December 9, 2020, 4:57pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/11 "2020-12-09T16:57:08Z")

</div>

> [@Max\_Desiatov](#):
>
> My understanding is that it is not a part of this proposal. It maybe be possible to provide an example with this + the Structured Concurrency proposal, but not with plain `async` / `await` . Structured concurrency API would give you a way to schedule tasks on queues etc.

Even so, it is clearly a significant motivating use-case, called out directly in the proposal.

In fact, I would say it is the only “interesting” use-case in the proposal. All the other examples show an async function being called essentially synchronously, where the code just waits for the `await` to complete.

If the intention is to allow interleaving, as it seems to be, then we should see what that will look like.

---

<div class="post-metadata">

**Author:** ![Jeehut](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jeehut/32/21743_2.png) [@Jeehut](https://forums.swift.org/u/Jeehut)\
**Post date:** [December 9, 2020, 6:08pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/12 "2020-12-09T18:08:52Z")

</div>

- What is your evaluation of the proposal?

Finally, it‘s here - I‘m loving it!

- Is the problem being addressed significant enough to warrant a change to Swift?

Yes, for sure!

- Does this proposal fit well with the feel and direction of Swift?

Absolutely! (Assuming the feel and direction are to become the best general purpose language with wide adoption out there for the next decade.)

- If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I used Kotlin Coroutines. This proposals is a much better design IMHO as it doesn’t rely on an IDE that fills in the gaps like marking asynchronous calls but instead builds the ‚await‘ keyword right into the language itself.

- How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

No sample code written, but read basically all related threads there is on the Swift forums (including most comments).

---

<div class="post-metadata">

**Author:** ![adamkemp](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/adamkemp/32/3017_2.png) [@adamkemp](https://forums.swift.org/u/adamkemp)\
**Post date:** [December 9, 2020, 6:39pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/13 "2020-12-09T18:39:50Z")

</div>

> [@Nevin](#):
>
> In fact, I would say it is the only “interesting” use-case in the proposal. All the other examples show an async function being called essentially synchronously, where the code just waits for the `await` to complete.

The presence of `await` does not mean that the call is synchronous. I think the confusion here, which is a common misunderstanding, is that the "wait" does not block the original thread. That's what "synchronous" would mean. Instead, the "wait" means "if this call needs to do something asynchronously then call me back later when it's finished". At that point the function is suspended, and the function gives up its use of the current thread, which can then move on to do other things.

Later, when that asynchronous work is complete, the function is resumed from where it left off (maybe or maybe not on the original thread). At this point, as with any other call-back-oriented code, the call stack will be different from what it was before the await.

It would help to separate in your mind the concepts of "synchronously" and "serially". The await causes the code to execute serially (which is not necessarily the case with a callback closure), but not synchronously. Synchronous would imply it never gives up control over the thread it's running on, and its call stack never changes. Serial just means the lines of code within that function progress in a way that matches the ordinary control flow you're used to.

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [December 9, 2020, 6:52pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/14 "2020-12-09T18:52:40Z")

</div>

> [@ben-cohen](#):
>
> - What is your evaluation of the proposal?

Very strong +1.

> [@ben-cohen](#):
>
> - Is the problem being addressed significant enough to warrant a change to Swift?

Yes, 100%. The lack of `async`/`await` was sorely missing in Swift for years. It was especially frustrating to use other languages that have this feature present, and then to come back to Swift, which still requires the use of delegate- or callback-based APIs. I really hope that won't be the case anymore.

> [@ben-cohen](#):
>
> - Does this proposal fit well with the feel and direction of Swift?

Yes. The introduced syntax is explicit enough, but introduces great productivity and QoL improvements when working with asynchronous APIs.

> [@ben-cohen](#):
>
> - If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I've used both Python and JavaScript extensively, where `async`/`await` work mostly the same for end users, with the only major difference being explicit error handling in Swift, which I do like. I also commend the general direction of the multiple concurrency proposals (structured concurrency, actors, `AsyncSequence` et al), and how well thought out they are. Seems like it was well worth the wait, and Swift is getting a much better support for concurrency than most of the mainstream languages!

> [@ben-cohen](#):
>
> - How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

I've been tracking discussions following the original concurrency manifesto by Chris Lattner, and some of the `async`/`await` threads that these forums saw over the years. I read the current proposal, and the rest of the concurrency proposals.

---

<div class="post-metadata">

**Author:** ![jdmcd](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jdmcd/32/22850_2.png) [@jdmcd](https://forums.swift.org/u/jdmcd)\
**Post date:** [December 9, 2020, 6:59pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/15 "2020-12-09T18:59:12Z")

</div>

> [@ben-cohen](#):
>
> What is your evaluation of the proposal?

Strong +1

> [@ben-cohen](#):
>
> Is the problem being addressed significant enough to warrant a change to Swift?

Absolutely - this is one of the major pain points remaining in the ecosystem, especially for server side applications.

> [@ben-cohen](#):
>
> Does this proposal fit well with the feel and direction of Swift?

I think so - I particularly like the use of keywords like `async` and `await` instead of native `Promise` implementations like Javascript started with.

> [@ben-cohen](#):
>
> If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

I've used futures/promises in Javascript/Typescript extensively and I'm excited to see that this proposal lines up with a lot of the syntax there. I think it reads clearly and is powerful for the user.

> [@ben-cohen](#):
>
> - How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quite a bit - I've been reading the proposals since they first went up a few weeks ago and participating in the discussions, and then of course did another review when this was posted.

---

<div class="post-metadata">

**Author:** ![Nevin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/nevin/32/617_2.png) [@Nevin](https://forums.swift.org/u/Nevin)\
**Post date:** [December 9, 2020, 7:16pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/16 "2020-12-09T19:16:44Z")

</div>

> [@adamkemp](#):
>
> The presence of `await` does not mean that the call is synchronous. I think the confusion here, which is a common misunderstanding, is that the "wait" does not block the original thread. That's what "synchronous" would mean. Instead, the "wait" means "if this call needs to do something asynchronously then call me back later when it's finished". At that point the function is suspended, and the function gives up its use of the current thread, which can then move on to do other things.
> 
> Later, when that asynchronous work is complete, the function is resumed from where it left off (maybe or maybe not on the original thread). At this point, as with any other call-back-oriented code, the call stack will be different from what it was before the await.
> 
> It would help to separate in your mind the concepts of "synchronously" and "serially". The await causes the code to execute serially (which is not necessarily the case with a callback closure), but not synchronously. Synchronous would imply it never gives up control over the thread it's running on, and its call stack never changes. Serial just means the lines of code within that function progress in a way that matches the ordinary control flow you're used to.

Unless I’ve missed something, the proposal does not show any examples of interleaving.

The proposal does not show any examples of the original thread continuing to do other things during the `await`.

That is what I am asking for examples of.

That seems to be the main purpose and primary motivation for this feature.

And the proposal shows zero examples of it.

The proposal does not adequately communicate how this feature is intended to be used.

Even if the mechanism for actually using the feature in that way has been split off into a separate proposal, it should still be explained here as motivation for this feature, with examples, so that reviewers of this proposal can understand what the purpose is and how it is intended to be used.

---

<div class="post-metadata">

**Author:** ![QuinceyMorris](https://avatars.discourse-cdn.com/v4/letter/q/d26b3c/32.png) [@QuinceyMorris](https://forums.swift.org/u/QuinceyMorris)\
**Post date:** [December 9, 2020, 7:54pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/17 "2020-12-09T19:54:46Z")

</div>

In the current (pre-`async`/`await`) world, the main thread/queue is _already_ asynchronous at the highest level. For example, consider a view controller:

```swift
override func viewWillAppear(_ animated: Bool) { … }
override func viewDidAppear(_ animated: Bool) { … }

```

The second of these is always called _after_ the first, but the timing is asynchronous — there is a time gap (analogous to a suspension point) between the two, during which _any other_ main thread code could execute.

The `async`/`await` proposal doesn't really change anything fundamental, except that it introduces suspension points _inside_ functions alongside the existing suspension points _between_ function invocations.

I think @Max_Desiatov is correct that you can't demonstrate the resulting interleaving solely in terms of base `async`/`await` syntax. However, there are lots of other ways of executing independent code on the same thread (e.g. using GCD as in the example I gave you over in the other thread).

---

<div class="post-metadata">

**Author:** ![Max\_Desiatov](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/max_desiatov/32/20654_2.png) [@Max\_Desiatov](https://forums.swift.org/u/Max_Desiatov)\
**Post date:** [December 9, 2020, 7:58pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/18 "2020-12-09T19:58:14Z")

</div>

> [@Nevin](#):
>
> Even if the mechanism for actually using the feature in that way has been split off into a separate proposal, it should still be explained here as motivation for this feature, with examples, so that reviewers of this proposal can understand what the purpose is and how it is intended to be used.

The proposal under review in its text already links to the structured concurrency proposal. Reviewers needing more context can freely follow the link. What would be the benefit of duplicating examples in two separate, but related proposals?

---

<div class="post-metadata">

**Author:** ![Jumhyn](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/jumhyn/32/3891_2.png) [@Jumhyn](https://forums.swift.org/u/Jumhyn)\
**Post date:** [December 9, 2020, 8:13pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/19 "2020-12-09T20:13:56Z")

</div>

> [@Nevin](#):
>
> The proposal does not show any examples of the original thread continuing to do other things during the `await` .
> 
> That is what I am asking for examples of.
> 
> That seems to be the main purpose and primary motivation for this feature.
> 
> And the proposal shows zero examples of it.
> 
> The proposal does not adequately communicate how this feature is intended to be used.

The proposal presents `async`/`await` as an answer to the (numerous) problems identified with the "completion handler" pattern, and the interleaving/"gives up the thread" behavior is already commonplace in these situations. Indeed, that's precisely _why_ you use a completion handler when scheduling UI work to be done after a long-running task: you _want_ to allow other work items to execute on the main thread before the task completes.

Perhaps the proposal could draw this point out a little more explicitly, but I don't think that the concept is quite as foreign as you're contending.

---

<div class="post-metadata">

**Author:** ![Karl](https://avatars.discourse-cdn.com/v4/letter/k/34f0e0/32.png) [@Karl](https://forums.swift.org/u/Karl)\
**Post date:** [December 9, 2020, 8:17pm UTC](https://forums.swift.org/t/se-0296-async-await/42605/20 "2020-12-09T20:17:40Z")

</div>

**What is your evaluation of the proposal?**

I started off as broadly +1, but on more careful reading of the proposal and allowing things to stew a bit, I'm not so sure. It's quite hard to judge without also considering the planned executor/continuation API (which I haven't looked at in as much detail). But even considering the `async/await` model proposed in this document as a kind of abstract concept, I have concerns with the programming model that I think merit further discussion.

1. Read-only async properties and subscripts should be allowed. The proposal says:

2. Cancellation.

**Is the problem being addressed significant enough to warrant a change to Swift?**  
**Does this proposal fit well with the feel and direction of Swift?**

It's fine, I guess. I'm a little concerned that we're doing this without a lot of the infrastructure other languages have (coroutines, generators).

**If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?**

I've mostly been using Swift since `async` really started taking the world by storm, so I've missed a lot of that. That said, I have heard criticisms from other developers that `async` ends up spreading to all areas of your code, and I could see similar things happening here. For example, with synchronous functions able to satisfy `async` protocol requirements, I could imagine lots of developers will default to making everything `async`. I'm not sure there is any way to avoid that, or what a better approach would be.

[Next page](https://forums.swift.org/t/se-0296-async-await/42605.md?page=2)
