<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 Sep 11, 2017, at 1:42 PM, Adam Kemp &lt;<a href="mailto:adam.kemp@apple.com" class="">adam.kemp@apple.com</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="Singleton" style="word-wrap: break-word; -webkit-nbsp-mode: 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="">Yes, this is a reasonable concern. &nbsp;We debated it heavily in the Swift 2 timeframe when introducing error handling (as other’s have pointed out, it works the same way).</div><div class=""><br class=""></div><div class="">This is a tradeoff between the readability benefits of marking non-obvious control flow vs the readability disadvantage of having noise in the code. Requiring marking on every async or throwing call is particularly bad in the case of chaining. &nbsp;Compare:</div><div class=""><br class=""></div><div class="">&nbsp; &nbsp;let x = try (try (try a.foo()).bar()).baz()</div><div class="">vs:</div>&nbsp; &nbsp;let x = try a.foo().bar().baz()<div class=""><br class=""></div><div class="">In the Swift 2 timeframe, we decided that in many cases, it is mostly obvious what APIs can throw, so one marker is enough. &nbsp;That said, there ARE potentially confusing cases, and some programmers may want to be more explicit about marking. &nbsp;This is why the compiler allows you to explicitly mark subexpressions if you’d like.</div><div class=""><br class=""></div><div class="">I believe that this design has served the community well, and I haven’t heard of serious problems with it. &nbsp;I’m pretty confident that async following the same model will have similar success.</div><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""></div></div></div></blockquote></div><br class=""><div class="">I think that decision makes sense for try/throws, but I feel like the await keyword is fundamentally different from that. The pitfalls of not understanding how the code is transformed and how it will behave at runtime are much greater with await than with try.</div><div class=""><br class=""></div><div class="">If you have a line of code with multiple expressions that can throw then the consequences of not knowing which particular one threw the error are minor. In most cases it doesn’t matter, and you would handle a given error the same regardless of which subexpression threw the error.</div><div class=""><br class=""></div><div class="">With await the function is actually broken up into pieces, and unrelated code can run in between those pieces on the same thread and/or the same queue. That has a much higher potential of leading to subtle bugs if you can’t see where those breaks are.</div></div></div></blockquote></div><br class=""><div class="">What sort of bugs? &nbsp;Can you please provide a concrete example we can discuss?</div><div class=""><br class=""></div><div class="">-Chris</div><div class=""><br class=""></div></body></html>