<html><head><meta http-equiv="Content-Type" content="text/html charset=utf-8"></head><body style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On Aug 18, 2017, at 2:09 PM, Adam Kemp <<a href="mailto:adam.kemp@apple.com" class="">adam.kemp@apple.com</a>> wrote:<br class=""><div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class="">On Aug 18, 2017, at 12:34 PM, Adam Kemp <<a href="mailto:adam.kemp@apple.com" class="">adam.kemp@apple.com</a>> wrote:<br class=""><div class=""><blockquote type="cite" class="">For instance, say you’re handling a button click, and you need to do a network request and then update the UI. In C# (using Xamarin.iOS as an example) you might write some code like this:<br class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">private async void HandleButtonClick(object sender, EventArgs e) {</div><div class=""> var results = await GetStuffFromNetwork();</div><div class=""> UpdateUI(results);</div><div class="">}</div></blockquote><div class=""><br class=""></div>This event handler is called on the UI thread, and the UpdateUI call must be done on the UI thread. The way async/await works in C# (by default) is that when your continuation is called it will be on the same synchronization context you started with. That means if you started on the UI thread you will resume on the UI thread. If you started on some thread pool then you will resume on that same thread pool.<br class=""></div></div></blockquote><div class=""><br class=""></div><div class="">I completely agree, I would love to see this because it is the most easy to reason about, and is implied by the syntax. I consider this to be a follow-on to the basic async/await proposal - part of the Objective-C importer work, as described here:</div><div class=""><a href="https://gist.github.com/lattner/429b9070918248274f25b714dcfc7619#fix-queue-hopping-objective-c-completion-handlers" class="">https://gist.github.com/lattner/429b9070918248274f25b714dcfc7619#fix-queue-hopping-objective-c-completion-handlers</a></div></div></div></div></blockquote><div class=""><br class=""></div><div class="">Maybe I’m still missing something, but how does this help when you are interacting only with Swift code? If I were to write an asynchronous method in Swift then how could I do the same thing that you propose that the Objective-C importer do? That is, how do I write my function such that it calls back on the same queue?</div></div></div></div></blockquote><div><br class=""></div>You’re right: if you’re calling something written in Swift, the ObjC importer isn’t going to help you.</div><div><br class=""></div><div>However, if you’re writing an async function in Swift, then it is reasonable for us to say what the convention is and expect you to follow it. Async/await doesn’t itself help you implement an async operation: it would be turtles all the way down… until you get to GCD, which is where you do the async thing.</div><div><br class=""></div><div>As such, as part of rolling out async/await in Swift, I’d expect that GCD would introduce new API or design patterns to support doing the right thing here. That is TBD as far as the proposal goes, because it doesn’t go into runtime issues.</div><div><div><br class=""></div><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class="">Another difference between the C# implementation and this proposal is the lack of futures. While I think it’s fair to be cautious about tying this proposal to any specific futures implementation or design, I feel like the value of tying it to some concept of futures was somewhat overlooked. For instance, in C# you could write a method with this signature:</div></div></div></blockquote>...<br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">The benefit of connecting the async/await feature to the concept of futures is that you can mix and match this code freely. The current proposal doesn’t seem to allow this. </div></div></div></blockquote><div class=""><br class=""></div><div class="">The current proposal provides an underlying mechanism that you can build futures on, and gives an example. As shown, the experience using that futures API would work quite naturally and fit into Swift IMO.</div></div></div></blockquote><br class=""></div><div class="">I feel like this is trading conceptual complexity in order to gain compiler simplicity. What I mean by that is that the feature feels harder to understand, and the benefit seems to be that this feature can be used more generally for other things. I’m not sure that’s a good tradeoff.</div><div class=""><br class=""></div><div class="">The other approach, which is to build a specific async/await feature using compiler transformations, may be less generic (yield return would have to work differently), but it seems (to me) easier to understand how to use.</div><div class=""><br class=""></div><div class="">For instance, this code (modified from the proposal):</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">@IBAction func buttonDidClick(sender:AnyObject) { </div><div class=""> doSomethingOnMainThread();</div><div class=""><div class=""> beginAsync {</div></div><div class=""> let image = await processImage()</div><div class=""><div class=""> imageView.image = image</div></div><div class=""><div class=""> }</div></div><div class=""> doSomethingElseOnMainThread();</div><div class="">}</div></blockquote><br class=""><div class="">Is less straightforward than this:</div><div class=""><br class=""></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class="">@IBAction async func buttonDidClick(sender:AnyObject) {</div><div class=""> doSomethingOnMainThread();</div><div class=""> let imageTask = processImage()</div><div class=""> doSomethingElseOnMainThread();</div><div class=""> imageView.image = await imageTask</div><div class="">}</div></blockquote></div></div></blockquote></div><br class=""><div class="">This isn’t a fair transformation though, and isn’t related to whether futures is part of the library or language. The simplification you got here is by making IBAction’s implicitly async. I don’t see that that is possible, since they have a very specific calling convention (which returns void) and are invoked by objc_msgSend. OTOH, if it were possible to do this, it would be possible to do it with the proposal as outlined.</div><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""></div></body></html>