<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=""><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Hi,</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class="">to help with async programming tasks, I could see the following affordances on async/await to be helpful:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">1. Make existing Continuation Passing Style (CPS) APIs available via async/await.</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">2. Await with timeouts.</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">3. Possibility to cancel awaits.</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">To be more specific:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Ad 1.&nbsp;</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">I think it could be helpful if an API like:&nbsp;</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`func foo(_ arg: Arg, completion: (val: Val) -&gt; Void)`</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">could be invoked like this:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`let val: Val = await foo(arg)`</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">(i.e, having a mapped signature like: `func foo(_ arg: Arg) async -&gt; Val`)</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Often, the completion takes an error argument:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`func bar(_ arg: Arg, completion: (val: Val?, err: Error?) -&gt; Void)`</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Calling it via async/await might look like this:</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">```</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">do {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; let val: Val = try await bar(arg)</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">} catch {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; // handle error</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">}</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">```</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">I could imagine that new type attributes are needed to make this happen:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">@continuation: the closure which continues the async control flow</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`func bar(_ arg: Arg, completion: @continuation (val: Val?, err: Error?) -&gt; Void)`</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">This function would transform to something like this:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`func bar(_ arg: Arg) throws async -&gt; Val`</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Some developers already have adopted a Result style - it would be nice to support the same conversion here too:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`func bar2(_ arg: Arg, completion: @continuation (result: Result&lt;Val&gt;) -&gt; Void)` -&gt;</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`func bar2(_ arg: Arg) throws async -&gt; Val`</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Maybe `Result` has to adopt a specific protocol to allow this.</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Ad 2 - Await with Timeouts</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">It could be helpful to have the option to specify how long an await should wait before throwing a timeout error:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">```</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">do {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; let val = try await(for: 2.718) bar(arg)</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">} catch AsyncError.timeout {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; // handle timeout</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">} catch {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; // handle other errors</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">}</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">```</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Ad 3 - Cancelation</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Sometimes, I maybe want to cancel an async operation.</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">```</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">class C {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; var task: CancelableTask&lt;Val&gt;?</div><p style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class="">&nbsp;&nbsp;<br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; func startProcess() {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; do {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; &nbsp; task = baz(arg)</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; &nbsp; let val = try await task!</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; &nbsp; …</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; } catch AsyncError.cancelation {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; &nbsp; // handle cancelation</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; } catch {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; &nbsp; // handle other errors</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; }</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; func cancelProcess() {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; task?.cancel()</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; }</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">}</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">```</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">To be cancelable, a function needs to support that:</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">```</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">func baz(_ arg: Arg) -&gt; CancelableTask&lt;Val&gt; {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; let task = CancelableTask&lt;Val&gt;()</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; let sess = URLSession.dataTask(with: arg.url) { data, resp, err in</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; &nbsp; // No automatic CPS conversion here as dataTask does not return Void</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; &nbsp; task.finish(with: data.val)</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; task.onCancellation {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; &nbsp; sess.cancel()</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; }</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp; &nbsp; return task</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">}&nbsp;</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">```</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`baz` would have an equivalent signature of:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`func baz(_ arg: Arg) throws async cancelable-&gt; Val`</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Then, the non-cancellable `bar` function from above could also be written as:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`func bar(_ arg: Arg) -&gt; Task&lt;Val&gt;` (aka. Promise, Future, …)</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">and the non-throwing `foo` function:</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`func foo(_ arg: Arg) -&gt; NonThrowingTask&lt;Val&gt;`</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Of course, work on concurrency in Swift has a much bigger scope than this laundry list of</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">&nbsp;on async/await capabilities.</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Cheers</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">Marc</div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div><div style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""><br class=""></div></body></html>