<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. </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: </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) -> 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 -> 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?) -> 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=""> 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=""> // 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?) -> 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 -> 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<Val>) -> Void)` -></div><div style="margin: 0px; font-size: 14px; line-height: normal;" class="">`func bar2(_ arg: Arg) throws async -> 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=""> 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=""> // 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=""> // 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=""> var task: CancelableTask<Val>?</div><p style="margin: 0px; font-size: 14px; line-height: normal; min-height: 17px;" class=""> <br class="webkit-block-placeholder"></p><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> func startProcess() {</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=""> task = baz(arg)</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> let val = try await task!</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> …</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> } catch AsyncError.cancelation {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> // handle cancelation</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=""> // 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;" class=""> func cancelProcess() {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> task?.cancel()</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;" 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) -> CancelableTask<Val> {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> let task = CancelableTask<Val>()</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> let sess = URLSession.dataTask(with: arg.url) { data, resp, err in</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> // No automatic CPS conversion here as dataTask does not return Void</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> task.finish(with: data.val)</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> }</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> task.onCancellation {</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> sess.cancel()</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> }</div><div style="margin: 0px; font-size: 14px; line-height: normal;" class=""> return task</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="">`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-> 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) -> Task<Val>` (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) -> NonThrowingTask<Val>`</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=""> 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>