<div dir="ltr">2017-08-21 2:20 GMT+09:00 John McCall via swift-evolution <span dir="ltr">&lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt;</span>:<br><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><div style="word-wrap:break-word"><span class="gmail-"><blockquote type="cite"><div>On Aug 19, 2017, at 7:17 PM, Chris Lattner via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><div><div style="word-wrap:break-word"><blockquote type="cite"><div>On Aug 19, 2017, at 8:14 AM, Karim Nassar via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" target="_blank">swift-evolution@swift.org</a>&gt; wrote:</div><br class="gmail-m_5864697011298285341Apple-interchange-newline"><div><div style="word-wrap:break-word"><div>This looks fantastic. Can’t wait (heh) for async/await to land, and the Actors pattern looks really compelling.</div><div><br></div><div>One thought that occurred to me reading through the section of the &quot;async/await&quot; proposal on whether async implies throws:</div><div><br></div><div>If ‘async&#39; implies ‘throws&#39; and therefore ‘await&#39; implies ‘try’, if we want to suppress the catch block with ?/!, does that mean we do it on the ‘await’ ? </div></div></div></blockquote><blockquote type="cite"><div style="word-wrap:break-word"><div><br></div><div><font face="Menlo">guard let foo = await? getAFoo() else {  …  }</font></div></div></blockquote><div><br></div><div>Interesting question, I’d lean towards “no, we don’t want await? and await!”.  My sense is that the try? and try! forms are only occasionally used, and await? implies heavily that the optional behavior has something to do with the async, not with the try.  I think it would be ok to have to write “try? await foo()” in the case that you’d want the thrown error to turn into an optional.  That would be nice and explicit.</div></div></div></blockquote><div><br></div></span>try? and try! are quite common from what I&#39;ve seen.</div></blockquote><div class="gmail_extra"><br></div><div class="gmail_extra">As analogous to `throws` and `try`, I think we have an option that `await!` means blocking.</div><div class="gmail_extra"><br></div><div class="gmail_extra">First, if we introduce something like `do/catch` for `async/await`, I think it should be for blocking. For example:</div><div class="gmail_extra"><br></div><div class="gmail_extra">```</div><div class="gmail_extra">do {</div><div class="gmail_extra">  return await foo()</div><div class="gmail_extra">} block</div><div class="gmail_extra">```</div><div class="gmail_extra"><br></div><div class="gmail_extra">It is consistent with `do/try/catch` because it should allow to return a value from inside `do` blocks for an analogy of `throws/try`.</div><div class="gmail_extra"><br></div><div class="gmail_extra">```</div><div class="gmail_extra">// `throws/try`</div><div class="gmail_extra">func foo() -&gt; Int {</div><div class="gmail_extra">  do {</div><div class="gmail_extra">    return try bar()</div><div class="gmail_extra">  } catch {</div><div class="gmail_extra">    ...</div><div class="gmail_extra">  }<br></div><div class="gmail_extra">}</div><div class="gmail_extra"><br></div><div class="gmail_extra">// `async/await`</div><div class="gmail_extra">func foo() -&gt; Int {</div><div class="gmail_extra">  do {</div><div class="gmail_extra">    return await bar()</div><div class="gmail_extra">  } block</div><div class="gmail_extra">}</div><div class="gmail_extra">```</div><div class="gmail_extra"><br></div><div class="gmail_extra">And `try!` is similar to `do/try/catch`.</div><div class="gmail_extra"><br></div><div class="gmail_extra">```</div><div class="gmail_extra">// `try!`</div><div class="gmail_extra">let x = try! foo()</div><div class="gmail_extra"><div class="gmail_extra">// uses `x` here</div><div class="gmail_extra"><br></div><div class="gmail_extra">// `do/try/catch`</div><div class="gmail_extra">do {<br></div></div><div class="gmail_extra">  let x = try foo()</div><div class="gmail_extra">  // uses `x` here</div><div class="gmail_extra">} catch {<br>  fatalError()<br>}</div><div class="gmail_extra">```</div><div class="gmail_extra"><br></div><div class="gmail_extra">If `try!` is a sugar of `do/try/catch`, it also seems natural that `await!` is a sugar of `do/await/block`. However, currently all `!` in Swift are related to a logic failure. So I think using `!` for blocking is not so natural in point of view of symbology.</div><div class="gmail_extra"><br></div><div class="gmail_extra">Anyway, I think it is valuable to think about what `do` blocks for `async/await` mean. It is also interesting that thinking about combinations of `catch` and `block` for `async throws` functions: e.g. If only `block`, the enclosing function should be `throws`.</div><div class="gmail_extra"><br></div><div class="gmail_extra">That aside, I think `try!` is not so occasional and is so important. Static typing has limitations. For example, even if we has a text field which allows to input only numbers, we still get an input value as a string and parsing it may fail on its type though it actually never fails. If we did not have easy ways to convert such a simple domain error or a recoverable error to a logic failure, people would start ignoring them as we has seen in Java by `catch(Exception e) {}`. Now we have `JSONDecoder` and we will see much more `try!` for bundled JSON files in apps or generated JSONs by code, for which decoding fails as a logic failure.</div><div class="gmail_extra"><br></div><div class="gmail_extra"><div><div class="gmail_signature">--<br>Yuta</div></div></div></div>