<html><head><meta http-equiv="Content-Type" content="text/html charset=us-ascii"></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 23, 2017, at 1:16 PM, 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=""><blockquote type="cite" 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;" class=""><br class="Apple-interchange-newline">On Aug 21, 2017, at 11:23 PM, Jonathan Hull via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:<br class=""><br class="">I have seen a lot of examples which use both do and beginAsync:<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>beginAsync {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>do {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>try await foo()<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>} catch let e {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>//Handle Error<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><br class="">I twitch every time I see this, because I thought part of the point of this was to avoid pyramiding. &nbsp;It would seem to be an argument for combining try and await, but as others have pointed out, that causes issues with try? and try!. &nbsp;I also really like the explicitness of knowing what could actually throw errors.<br class=""><br class="">I propose that we instead combine do and beginAsync. &nbsp;There are 3 cases:<br class=""><br class=""><br class="">1) Just throws (i.e what we have now):<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>do {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>try foo()<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>} catch let e {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>//Handle Error<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><br class=""><br class="">2) Just async (no catch needed):<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>do async {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>await foo()<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><br class=""><br class="">3) Both throws and async:<br class=""><br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>do async {<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>try await foo()<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}catch let e{<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span><span class="Apple-tab-span" style="white-space: pre;">        </span>//It would be a compiler error not to have a catch statement when there is a try in the do block.<br class=""><span class="Apple-tab-span" style="white-space: pre;">        </span>}<br class=""><br class=""><br class="">This feels much less messy to me, and will avoid unnecessary pyramids while still allowing throws and async to be separately declared.<br class=""><br class="">Thanks,<br class="">Jon<br class=""></blockquote><br 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=""><span 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; float: none; display: inline !important;" class="">The proposal is perhaps a bit beginAsync-heavy because it puts a lot of attention on how to adapt existing frameworks to work with coroutines. My feeling is that, in a system with frameworks that have more fully adopted coroutines in all the appropriate places, that you won't need to explicitly enter an async context as frequently since more contexts will already be `async` where they need to be, and that in the situations where you do need to enter a new async context, raw `beginAsync` won't be the best way to do so. `beginAsync` is still going to begin its coroutine body immediately on the current thread, but you're likely to want to associate it with a specific context using something like a version of dispatch_async that takes a `() async -&gt; ()` block. There are also APIs that could provide for coordination with the coroutine, such as a constructor for Future&lt;T&gt; that takes an () async -&gt; T block which is automatically fulfilled by the completion of the block. I'm not against the idea of providing language sugar to make working with coroutines nicer (that is, after all, their whole reason to exist!), but I'm not sure this is the right thing to sugar, and we can always add sugar later once the core language model is set.</span><br 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=""></div></blockquote><div><br class=""></div></div>Right. &nbsp;I would only add to this that I'm specifically worried about adding features that make <i class="">blocking the current thread</i>&nbsp;more sugared.<div class=""><br class=""></div><div class="">John.</div></body></html>