# \[Concurrency\] Asynchronous functions

**URL:** <https://forums.swift.org/t/concurrency-asynchronous-functions/41619>\
**Category:** Pitches\
**Tags:** concurrency\
**Created:** [October 30, 2020, 6:35pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619 "2020-10-30T18:35:30Z")\
**Posts on this page:** 20\
**Page:** 4

<div class="post-metadata">

**Author:** ![John\_Lin](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_lin/32/1944_2.png) [@John\_Lin](https://forums.swift.org/u/John_Lin)\
**Post date:** [November 1, 2020, 12:03pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/62 "2020-11-01T12:03:23Z")

</div>

> [@unixzii](#):
>
> This can be implemented by simply wrapping the `Task.runDetached` method like this:
> 
> ```swift
> func asyncWrapper<T>(_ operation: () async -> T, completion: (T) -> Void) {
> let _ = Task.runDetached {
> let result = await operation()
> completion(result)
> }
> }
> 
> ```
> 
> This is useful, look forward to a polished way to do so.

Thanks for great solution,  
the `public func get() async throws -> Success { ... }`  
interface make it looks like it requires another `await`.  
Maybe we should have a `public func get(completion: (Success)->Void) throws -> Void` interface as well.  
But that should belongs to the structured concurrency thread.

---

<div class="post-metadata">

**Author:** ![unixzii](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/unixzii/32/13634_2.png) [@unixzii](https://forums.swift.org/u/unixzii)\
**Post date:** [November 1, 2020, 12:10pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/63 "2020-11-01T12:10:15Z")

</div>

The most common scenario I can think of is some UI components trigger an action (eg. by tapping a button), and that action is an async function. In this scenario, we might not want a result value, the async function itself will do some asynchronous things and manipulate the UI.

---

<div class="post-metadata">

**Author:** ![michelf](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/michelf/32/1180_2.png) [@michelf](https://forums.swift.org/u/michelf)\
**Post date:** [November 1, 2020, 12:32pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/64 "2020-11-01T12:32:11Z")

</div>

> [@Douglas\_Gregor](#):
>
> Extisting synchronous, blocking APIs are likely to get augmented with asynchronous APIs, and we want the asynchronous code to prefer to use those new asynchronous APIs.

What happens if someone does it the other way? I could write a synchronous function in an actor, and then provide an asynchronous version that can be called from outside the actor. If the asynchronous function attempts to call the synchronous one as its implementation, it’ll likely call itself instead if the have the same name.

Also, if you are in an asynchronous context, you could still prefer the synchronous version to avoid adding a suspension point that would allow other tasks to change the state mid-way in your function. (I realize it would be better to only block tasks for this actor without blocking the whole thread, had we a way to do than.)

---

<div class="post-metadata">

**Author:** ![nikstar](https://avatars.discourse-cdn.com/v4/letter/n/34f0e0/32.png) [@nikstar](https://forums.swift.org/u/nikstar)\
**Post date:** [November 1, 2020, 12:50pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/65 "2020-11-01T12:50:34Z")

</div>

We should consider making `await` imply `throws`. This would declutter the call site. Async operations are often throwing:

- loading web resources: definitely throwing
- file IO: usually throwing
- costly operations: can go either way
- UI actions: the only case I can think of right now that cannot be throwing

This was discussed in previous threads and the response was pretty positive. What are the benefits of proposed syntax?

---

<div class="post-metadata">

**Author:** ![benjamin.g](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@benjamin.g](https://forums.swift.org/u/benjamin.g)\
**Post date:** [November 1, 2020, 2:25pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/66 "2020-11-01T14:25:09Z")

</div>

> [@John\_McCall](#):
>
> When control returns to an asynchronous function, it picks up exactly where it was. That doesn’t necessarily mean that it’ll be running on the exact same thread it was before, because the language doesn’t guarantee that after a suspension. In this design, threads are mostly an implementation mechanism, not a part of the intended interface to concurrency. However, many asynchronous functions are not just asynchronous: they’re also associated with specific actors (which are the subject of a separate proposal), and they’re always supposed to run as part of that actor. Swift does guarantee that such functions will in fact return to their actor to finish executing. Accordingly, libraries that use threads directly for state isolation—for example, by creating their own threads and scheduling tasks sequentially onto them—should generally model those threads as actors in Swift in order to allow these basic language guarantees to function properly.

Does it mean that, without considering actors, writing something like :

> func onRefreshButtonClick() {  
> self.data = await jsonAPI.fetchData()  
> tableView.reloadData()  
> }

from a viewcontroller running on the main thread is a very bad idea , because by default we have no guarantee that the fetchData() api will return on the main thread ?

This is nothing new per say, and a closure callback would have the same drawback. However the word "await" in itself probably implies that the function code will actually "resume" where it was (thread included).

I may have misunderstood the proposal, and i'm clearly not knowledgeable of implementation details, but wouldn't it be safer to have await always returns to the original thread by default ? (I understood that this feature is meant to work together with actors, which makes things more explicit, but i believe the feature should work nicely on its own)

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [November 1, 2020, 2:56pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/67 "2020-11-01T14:56:28Z")

</div>

> [@benjamin.g](#):
>
> Does it mean that, without considering actors, writing something like :
> 
> > func onRefreshButtonClick() {  
> > self.data = await jsonAPI.fetchData()  
> > tableView.reloadData()  
> > }
> 
> from a viewcontroller running on the main thread is a very bad idea , because by default we have no guarantee that the fetchData() api will return on the main thread ?

To “get” how this all will work forget for a moment that threads exist 🙂

What code that runs like what you said would look like is this:

```swift
@MainActor // or UIActor tho I lean to saying “Main” but maybe we’d alias “UI” too?
func onRefreshButtonClick() async { // must be async to await on anything
    self.data = await jsonAPI.fetchData()
    tableView.reloadData()
}

```

As such, this function must respect actor rules — the actor may only execute on its executor; The executor happens to be the “main” or “ui” one, which happens to be the “main/ui” thread. But semantically all we care about is “actor code always executes on the right executor” and some actors have special executors.

So to answer your question — execution (`tableView.reloadData()`) will resume on the right actor/executor/(internally: thread). and there’s no need make any extra steps to make it do the right thing 👍

Hope this helps,

// edit 1: fixed typos

---

<div class="post-metadata">

**Author:** ![Lantua](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/lantua/32/8868_2.png) [@Lantua](https://forums.swift.org/u/Lantua)\
**Post date:** [November 1, 2020, 3:03pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/68 "2020-11-01T15:03:13Z")

</div>

I stumbled upon some interesting case about overloading:

```swift
actor class X {
    func foo() {
        // Do some work
    }

    // Async wrapper
    func foo() async {
        foo() // Error: call is not marked with 'await'
    }
}

```

You cannot wrap sync `foo` inside an async function of the same name (to allow access from outside of actor, mentioned in another thread) because the compiler (current toolchain) is thinking that I intend to use the async function, which would cause infinite-loop. Maybe we can make sure that it _doesn't do that_ but that's a very sharp edge.

* * *

> [@ktoso](#):
>
> As such, this function must resect actor rules — the actor may only execute on it’s executor; The executor happens to be the “main” or “ui” one, which happens to be the “main/ui” thread.

What's the semantic for `await`-ing on actor-isolated async method?

```swift
@MainActor
func foo() async {
  let a = await task1()
  let b = await task2()
}

```

Does it need to jump back to `MainActor` between `a` and `b`? What happens if both `task1` and `task2` are actor-isolated?

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [November 1, 2020, 3:24pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/69 "2020-11-01T15:24:10Z")

</div>

> [@Lantua](#):
>
> What's the semantic for `await` -ing on actor-isolated async method?
> 
> ```swift
> @MainActor
> func foo() async {
> let a = await task1()
> let b = await task2()
> }
> 
> ```
> 
> Does it need to jump back to `MainActor` between `a` and `b` ? What happens if both `task1` and `task2` are actor-isolated?

The rule is simple: Each actor must execute on its executor, this is how the model achieves thread safety (and sanity). There if the caller, task1 and task2 are on different actors, there would be hops back and forth, yes — that’s semantically what was asked for by such code. If they’re all the same actor, there’s no hops.

These hops can sometimes be optimized away, under special circumstances, but semantically think about it the way as phrased above.

This is kind of the wrong thread for it... let’s keep actors chat to the actors thread please if we’d like to continue this thread.

---

<div class="post-metadata">

**Author:** ![benjamin.g](https://avatars.discourse-cdn.com/v4/letter/b/9fc29f/32.png) [@benjamin.g](https://forums.swift.org/u/benjamin.g)\
**Post date:** [November 1, 2020, 3:50pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/70 "2020-11-01T15:50:07Z")

</div>

Does this mean await /async isn't meant to be used outside actors ?

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [November 1, 2020, 5:38pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/71 "2020-11-01T17:38:34Z")

</div>

`async` functions can absolutely be used outside of actors. However, the assumption is that actors are what impose correctness requirements on where code must be running, so if a function isn’t an actor function, there must not be any such requirements (until the function returns, at any rate).

---

<div class="post-metadata">

**Author:** ![frameworklabs](https://avatars.discourse-cdn.com/v4/letter/f/13edae/32.png) [@frameworklabs](https://forums.swift.org/u/frameworklabs)\
**Post date:** [November 1, 2020, 6:51pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/72 "2020-11-01T18:51:20Z")

</div>

Is it possible to call an `async` function without `await`-ing if am not interested in the returned value (or don’t care about the proper continuation flow ) - i.e. kind of a `oneway` semantics?

---

<div class="post-metadata">

**Author:** ![John\_McCall](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/john_mccall/32/1351_2.png) [@John\_McCall](https://forums.swift.org/u/John_McCall)\
**Post date:** [November 1, 2020, 6:53pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/73 "2020-11-01T18:53:25Z")

</div>

We intentionally do not want to make that very easy because it undermines structured concurrency, but you can create a detached task to do it, and the as-yet-unpitched `asyncHandler` feature is meant to support certain use-patterns that typically favor this.

---

<div class="post-metadata">

**Author:** ![masters3d](https://avatars.discourse-cdn.com/v4/letter/m/c4cdca/32.png) [@masters3d](https://forums.swift.org/u/masters3d)\
**Post date:** [November 1, 2020, 10:13pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/74 "2020-11-01T22:13:23Z")

</div>

In the current design all async functions have to be in an async context. Is there a way to design an scape hatch to block results of awaiting async function in a way allowing synchronous function call async functions like in dotNet’s Task.Result [1]

Similar to what we do with throwing functions with `try?`; could we have `await?` that wraps async functions results into a Result?

[1]

> **[How to: Return a Value from a Task](https://learn.microsoft.com/en-us/dotnet/standard/parallel-programming/how-to-return-a-value-from-a-task)**
>
> See how to use the System.Threading.Tasks.Task type to return a value from the Result property in .NET.

---

<div class="post-metadata">

**Author:** ![Chris\_Lattner3](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/chris_lattner3/32/348_2.png) [@Chris\_Lattner3](https://forums.swift.org/u/Chris_Lattner3)\
**Post date:** [November 1, 2020, 10:35pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/75 "2020-11-01T22:35:19Z")

</div>

> [@Douglas\_Gregor](#):
>
> To clarify, it is not the presence of `await` that changes overloading. When you are within an asynchronous function, we prefer `async` functions. When you are within a synchronous function, we prefer synchronous functions.

Aha, I didn't understand that at all. I agree with you that this is a lot more predictable, and has advantages for cases where you want to introduce async versions of existing methods (but see @Lantua's [comment above](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/68))

> [@Douglas\_Gregor](#):
>
> Extisting synchronous, blocking APIs are likely to get augmented with asynchronous APIs, and we want the asynchronous code to prefer to use those new asynchronous APIs.

Ok, I agree that this is a useful thing to be able to do. Have you considered tightly scoping this? You could have an attribute (similar but different to `@ _disfavoredOverload`) that enables the otherwise-forbidden overload for just this one case with effectively the same semantics you describe, but more narrowly specified.

> [@Douglas\_Gregor](#):
>
> but this particular example is a tiny syntactic optimization of the kind that a Fix-It could introduce when it comes up.

Got it, I still think subtyping is important, but I agree that the closure-expression case isn't the important example.

> [@Douglas\_Gregor](#):
>
> The `throws` one keeps the error parameter but changes its type to `()` , so your call looks like:
> 
> ```swift
> try object.callThrowingThing(a, error: ())
> 
> ```
> 
> It's quite baroque, and I wish we hadn't done that. The corollary for async would be `async: ()` , which I wouldn't want to do. If we dropped overloading of `async` and non- `async` , I'd lean toward appending an `Async` or `Asynchronously` suffix to the base name.

Oh wow, didn't know that. I agree with you -- adding an `Async` suffix (like C# does) seems like a much more reasonable disambiguation here.

Thanks Doug!

-Chris

---

<div class="post-metadata">

**Author:** ![MarcusSmith](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/marcussmith/32/10346_2.png) [@MarcusSmith](https://forums.swift.org/u/MarcusSmith)\
**Post date:** [November 2, 2020, 1:29am UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/76 "2020-11-02T01:29:39Z")

</div>

I have to say that I'm really excited about this feature overall and think that the API for composing async functions looks great. Even in the full proposal, I don't see anything about how async functions interact with other times of asynchronous code, though.

How can an async function be made that interacts with closure-based APIs or Future based APIs like SwiftNIO? In other languages with async / await, at least ones that I'm familiar with, they all have some kind of Future type that is returned from async functions, which has a clear way of being created from a closure or other future / promise types, but I'm having trouble imagining how it would look when the async nature is part of the function signature but not the return type.

I'm particularly interested in how async / await works with NIO's EventLoopFuture, because server side swift currently suffers from the same pyramid of death problems noted in the proposal.

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [November 2, 2020, 3:29am UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/77 "2020-11-02T03:29:57Z")

</div>

Hi Marcus,

> [@MarcusSmith](#):
>
> How can an async function be made that interacts with closure-based APIs [...]?

This is covered in the full proposal on structured concurrency, the last section in [Structured concurrency: Low-level code and integrating with legacy APis with `UnsafeContinuation`](https://github.com/DougGregor/swift-evolution/blob/structured-concurrency/proposals/nnnn-structured-concurrency.md#low-level-code-and-integrating-with-legacy-apis-with-unsafecontinuation), please have a look.

> [@MarcusSmith](#):
>
> [...] or Future based APIs like SwiftNIO?

> [@MarcusSmith](#):
>
> I'm particularly interested in how async / await works with NIO's EventLoopFuture, because server side swift currently suffers from the same pyramid of death problems noted in the proposal.

Please refer to this thread on NIO adoption of the concurrency features: [Future of Swift-NIO in light of Concurrency Roadmap](https://forums.swift.org/t/future-of-swift-nio-in-light-of-concurrency-roadmap/41633)

Long story short: there are a few "steps" in adoption and yes this proposal should solve the "pyramid of doom" issues you allude to in server-side frameworks.

> [@MarcusSmith](#):
>
> In other languages with async / await, at least ones that I'm familiar with, they all have some kind of Future type that is returned from async functions, which has a clear way of being created from a closure or other future / promise types, but I'm having trouble imagining how it would look when the async nature is part of the function signature but not the return type.

Future values which are free to "pass around" undermine structured-concurrency and thus are a bit discouraged by this design. Please have a look at the structured concurrency design to get a feeling for this.

"Futures" still exist though -- they are called `Task.Handle` but should be used rarely because they miss out on some cool automatic context/priority/deadline propagation as well as bounded concurrency features.

---

<div class="post-metadata">

**Author:** ![anandabits](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/anandabits/32/355_2.png) [@anandabits](https://forums.swift.org/u/anandabits)\
**Post date:** [November 2, 2020, 4:38am UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/78 "2020-11-02T04:38:32Z")

</div>

> Asynchronous programs that need to do intense computation should generally run it in a separate context.

It would be helpful to see an example of how to implement this. Do you mean to suggest using a detached task? I think having guidelines about when those are appropriate would be useful. I'm especially concerned about scenarios where they _should_ be used and people don't use them because they are less convenient.

> When that’s not feasible, there will be library facilities to artificially suspend and allow other operations to be interleaved.

In most cases, wouldn't a well-behaved long-running computation periodically check for cancellation? I imagine a convenient way to implement both cancellation checking and suspension would be something like `func throwIfCancelled() async throws`. Calling this function periodically would both introduce a suspension point and abort if the result is no longer required.

> [@nikstar](#):
>
> We should consider making `await` imply `throws` . This would declutter the call site. Async operations are often throwing:

Further, it is necessary if we choose implicit task cancellation at suspension points (something I think is a good idea).

---

<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:** [November 2, 2020, 4:54am UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/79 "2020-11-02T04:54:22Z")

</div>

> [@Lantua](#):
>
> You cannot wrap sync `foo` inside an async function of the same name (to allow access from outside of actor, mentioned in another thread) because the compiler (current toolchain) is thinking that I intend to use the async function, which would cause infinite-loop. Maybe we can make sure that it _doesn't do that_ but that's a very sharp edge.

The compiler is working as the proposal states it should. The shortest trick if you want to implement your asynchronous function in terms of a synchronous one with the same signature---which I'm honestly a bit dubious about in the first place---is to wrap the call in a (non-async) closure, e.g.,

```swift
{ foo() }()

```

We could probably come up with a clearer way.

Doug

---

<div class="post-metadata">

**Author:** ![ktoso](https://sea2.discourse-cdn.com/swift/user_avatar/forums.swift.org/ktoso/32/44526_2.png) [@ktoso](https://forums.swift.org/u/ktoso)\
**Post date:** [November 2, 2020, 4:58am UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/80 "2020-11-02T04:58:58Z")

</div>

> [@anandabits](#):
>
> I imagine a convenient way to implement both cancellation checking and suspension would be something like `func throwIfCancelled() async throws` . Calling this function periodically would both introduce a suspension point and abort if the result is no longer required.

This exists and is called `checkCancellation()`, please refer to the structured concurrency proposal: [https://github.com/DougGregor/swift-evolution/blob/structured-concurrency/proposals/nnnn-structured-concurrency.md#cancellation](https://github.com/DougGregor/swift-evolution/blob/structured-concurrency/proposals/nnnn-structured-concurrency.md#cancellation)

---

<div class="post-metadata">

**Author:** ![jawbroken](https://avatars.discourse-cdn.com/v4/letter/j/cc9497/32.png) [@jawbroken](https://forums.swift.org/u/jawbroken)\
**Post date:** [November 2, 2020, 2:31pm UTC](https://forums.swift.org/t/concurrency-asynchronous-functions/41619/81 "2020-11-02T14:31:25Z")

</div>

> **Rationale** : This order restriction is arbitrary, but it's not harmful, and it eliminates the potential for stylistic debates.

I'm not sure about this for two reasons. Firstly, I believe it's unprecedented in the language to require that a semantically unordered list be placed in an arbitrary order. These concerns are currently, and probably rightfully, left to a linter to enforce. e.g. There's no enforced order for attributes like these:

```swift
class C {
  @discardableResult @inlinable @objc func f() -> Int { 0 }
  @objc @inlinable @discardableResult func g() -> Int { 0 }
  // … etc
}

```

Secondly, there's no proposed general principle here, just “the order is async throws”, which makes it unclear if/how to apply it to other parts of the language (like the above example), hard to remember, and hard to extend in future. What do you do if there's a new word that can go in this position, like a new keyword or a user-defined token (e.g. I think this is where a general effects system would live)? Would the rule be “alphabetical order”? Does this apply to both the definition and the call site? What if the call site words alphabetise in a different order than the definition site words?

I would prefer that these semantically unordered lists of attributes/keywords remain unordered for simplicity.

[Previous page](https://forums.swift.org/t/concurrency-asynchronous-functions/41619.md?page=3)

[Next page](https://forums.swift.org/t/concurrency-asynchronous-functions/41619.md?page=5)
