<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Aug 22, 2017, at 9:32 AM, Joe Groff via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><blockquote type="cite" class="" style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; orphans: auto; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; widows: auto; word-spacing: 0px; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class="" style="font-size: 15px;"><span class="" style="background-color: rgb(255, 255, 255);"><font color="#24292e" class=""><b class="">async&nbsp;as a subtype of&nbsp;throws&nbsp;instead of orthogonal to it</b></font></span></div><div class=""><span class="" style="background-color: rgb(255, 255, 255);"><font color="#24292e" class=""><br class=""></font></span></div><div class=""><span class="" style="background-color: rgb(255, 255, 255);"><font color="#24292e" class="">I’ve been thinking a lot about this since the proposal came out and I see a few serious&nbsp;</font></span><font color="#24292e" class="">disadvantages at making async a subtype of throws which might benefit from being discussed or/and mentioned in the proposal.</font></div><div class=""><font color="#24292e" class=""><br class=""></font></div><div class=""><font color="#24292e" class="">1. We loose the&nbsp;automatic documentation<span class="Apple-converted-space">&nbsp;</span><font face="Menlo" class="">try</font><span class="Apple-converted-space">&nbsp;</span>provides for signaling failable functions:</font></div><div class=""><br class=""></div><div class=""><font color="#24292e" face="Menlo" class="">let image = await downloadImage()</font></div><div class=""><font color="#24292e" face="Menlo" class="">let processedImage = await processImage(image)</font></div><div class=""><font color="#24292e" face="Menlo" class="">await present(MyViewController(image: image))</font></div><div class=""><font color="#24292e" class=""><br class=""></font></div><div class=""><font color="#24292e" class="">In my example,<span class="Apple-converted-space">&nbsp;</span><font face="Menlo" class="">downloadImage</font><span class="Apple-converted-space">&nbsp;</span>can fail because of network conditions,<span class="Apple-converted-space">&nbsp;</span><font face="Menlo" class="">processImage</font><span class="Apple-converted-space">&nbsp;</span>can not fail, and<span class="Apple-converted-space">&nbsp;</span><font face="Menlo" class="">present</font><span class="Apple-converted-space">&nbsp;</span>is the UIKit function which presents view controllers and it can’t fail either. But that’s not obvious from reading the code. We’ve lost information.</font></div></div></div></blockquote></div></div></div></div></blockquote><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class=""><br class=""></div><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">This seems like a similar pitfall to too narrow exception types that we try to avoid with `throws`. Saying that even a long-lived computation like processImage can't throw is a brittle architectural choice, since you may need to build in support for cancellation at some point, and if you ever decide to offload the computation to a GPU, coprocessor, or out-of-process worker, then it will be able to fail at that point.</div></div></div></div></blockquote><div><br class=""></div><div>You may be able to handle cancellation by abandoning the completion, rather than returning an error. And I can't imagine the error behavior of a low-level operation like `processImage(_:)` would ever bubble back up into the UI, so you can incorporate that error logic into the async function. (For instance, if you want to do the operation on the GPU but fall back to the CPU if it fails, then do that fallback inside `processImage(_:)`.)</div><div><br class=""></div><div>And if I'm wrong? Well, then you'll add `throws` and the compiler will tell you where to insert error handling. The switch from "zero errors" to "some errors" is much simpler than the switch from "N errors" to "N+1 errors". And remember, if the code previously couldn't throw in practice, any error handling code the user might have written to placate the compiler has probably never been exercised. There's a pretty good chance they used `try!` or empty `catch` blocks to quickly dispose of the non-existent errors. The compiler can tell you where you need to add error-handling code, but it can't tell you where your error-handling code is useless or wrong.</div><br class=""><blockquote type="cite" class=""><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;"><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-caps: normal; font-weight: normal; letter-spacing: normal; text-align: start; text-indent: 0px; text-transform: none; white-space: normal; word-spacing: 0px; -webkit-text-stroke-width: 0px;" class="">It's not clear to me why `present` would be async here; it seems to me like a fire-and-forget kind of operation you don't want to wait for.</div></div></div></div></blockquote></div><div class=""><br class=""></div><div class="">The `UIViewController.present` method has a completion block; I assume David Hart is thinking that `await` here would cause the subsequent code to run once the view controller finished presenting.</div><div class=""><br class=""></div><div class="">(Which brings up an interesting point: there are some APIs with completion blocks that you only occasionally use. For these APIs, it might make sense to have an `ignore` counterpart to `await` or something, and that counterpart seems like it might make `beginAsync` redundant.)</div><br class=""><div class="">
<span class="Apple-style-span" style="border-collapse: separate; color: rgb(0, 0, 0); font-family: Helvetica; font-style: normal; font-variant: normal; font-weight: normal; letter-spacing: normal; line-height: normal; orphans: 2; text-align: auto; text-indent: 0px; text-transform: none; white-space: normal; widows: 2; word-spacing: 0px; -webkit-border-horizontal-spacing: 0px; -webkit-border-vertical-spacing: 0px; -webkit-text-decorations-in-effect: none; -webkit-text-size-adjust: auto; -webkit-text-stroke-width: 0px;  "><div class=""><div style="font-size: 12px; " class="">--&nbsp;</div><div style="font-size: 12px; " class="">Brent Royal-Gordon</div><div style="font-size: 12px; " class="">Architechies</div></div></span>

</div>
<br class=""></body></html>