[swift-evolution] New async keyword usage

Trevör Anne Denise trevor.annedenise at icloud.com
Fri Aug 25 17:38:21 CDT 2017

First of all, thank you to everyone for reacting ! :)

Taking the messages in chronological order :

> Wallacy <wallacyf at gmail.com> 
> Interesting, its syntax seems to improve the "fire and forget" issue.
> @IBAction func buttonClicked() {
> 	async downloadAndUpdateImageView()
> }

While this could be nice it would indeed not be needed in this case @IBAction methods were async as Chris Lattner says.

> func SomethingUsingUser() -> Void {
> 	var user = await getUser() //Only here
> 	printf(user.age > 21 ? "Let's Drink" : "See you later!")

I don't have a lot of experience with async await syntaxes, but if I understand correctly the proposal and the way async/await works, doing that inside of a non-async function would be problematic as this would block the thread and wouldn't clearly show that calling your function would be blocking (being forced to marked a function as async and the imposed language syntax at call site fixes this issue).
That's why I only proposed "async outside of await" and not "await outside of async", because async outside of await would still enable the compiler to prevent issues like the aforementioned one thanks to a Future like behaviour.


> Chris Lattner <clattner at nondot.org> 
> Yes, it is entirely possible that we will want to provide more syntactic sugar than the proposal suggests: the proposal is intentionally designed to be minimal, so we can get it in place, get experience using it, then decide whether any specific syntactic pain point is significant enough to be worth adding additional sugar/complexity.
> As has been mentioned in other threads, the hope is that “beginAsync” is actually extremely rare in practice.  If that is the case, there is little point to sugaring it.
> -Chris

The second part of my proposition is indeed more syntactic sugar if beginAsync ends up being rarely used in practice, but about the first part of my explanation (using async inside of async functions to provide a future like syntax), would it enable to both to drastically reduce the syntactic complexity of async/await and to hide away implementation giving more freedom for future Swift releases as Wallacy and Jonathan Hull suggested?

Thank you ! :)

> Wallacy <wallacyf at gmail.com <mailto:wallacyf at gmail.com>> 
> Using only async/await is pretty easy to learn and teach.
> And after that, "Future" can be implement in any way because will not be a
> public API anymore (I do not know, but there may also be some opportunities
> for optimization as well), and we only need to care about when we need to
> "keep the reference" from some async call.
> And possibly, they will not need to create any Future type! The variable
> type will be "async User" as long as it is not "unwrapped". (
> suspend/defer/abandon still possible)

Using async at call site would indeed (in my opinion) make async/await easier to learn (especially given the parallel with optional unwrapping and similarities with other behaviours of Swift, including possible async vars of Actors maybe?).

I'd be interested to know what would be the ramifications of promoting async at type level as you propose, what would be the pros and cons of such an approach ? I'd be interested to get other opinions about it ! :)

In my first idea async at call site would be synthesising a Future<T> just as T? synthesises Optional<T>, but I'd be interested to know too if hiding implementation details would have any advantages for the future of Swift ? Making things more flexible maybe?

> Jonathan Hull jhull at gbis.com 

> This looks somewhat similar to a future, but you can’t interact with it as a separate type of object.  The value above is just a UIImage, but with a compiler flag/annotation that forces me to call await on it before it can be accessed/used.  The compiler has a lot more freedom to optimize/reorganize things behind the scenes, because it doesn’t necessarily need to make an intermediate object.

As for the message of Wallacy I'd be interested the pros and cons of hiding the implementation details ! :)

> To prove (or potentially disprove) my assertion that this is not just sugar, how would you accomplish the following under the current proposal?
> 	let a = async longCalculationA()
> 	let b = async longCalculationB() //b doesn’t wait for a to complete before starting
> 	let c = async longCalculationC() //c doesn’t wait for a or b
> 	let result = await combineCalculations(a: a, b: b, c: c) //waits until a, b, and c are all available

Would this be implemented differently than with Futures? I don't have much experience with concurrency, but I don't see how this would be handled differently than by using Futures, internally ? (at least for this case)

> Florent Vilmart florent at flovilmart.com 

> Probably with:
> let a = longCalculationA()
> let b = longCalculationB() //b doesn’t wait for a to complete before starting
> let c = longCalculationC() //c doesn’t wait for a or b
> let (aResult, bResult, cResult) = await Future.collect(a, b, c) //waits until a, b, and c are all available

This isn't possible with the proposed async/await syntax, is it ? 

Thank you everyone !! :)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.swift.org/pipermail/swift-evolution/attachments/20170826/9e0273d8/attachment.html>

More information about the swift-evolution mailing list