<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 20, 2017, at 3:56 PM, Yuta Koshizawa <<a href="mailto:koher@koherent.org" class="">koher@koherent.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div dir="ltr" class="">2017-08-21 2:20 GMT+09:00 John McCall via swift-evolution <span dir="ltr" class=""><<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>></span>:<br class=""><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" class=""><span class="gmail-"><blockquote type="cite" class=""><div class="">On Aug 19, 2017, at 7:17 PM, Chris Lattner via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><div class=""><div style="word-wrap:break-word" class=""><blockquote type="cite" class=""><div class="">On Aug 19, 2017, at 8:14 AM, Karim Nassar via swift-evolution <<a href="mailto:swift-evolution@swift.org" target="_blank" class="">swift-evolution@swift.org</a>> wrote:</div><br class="gmail-m_5864697011298285341Apple-interchange-newline"><div class=""><div style="word-wrap:break-word" class=""><div class="">This looks fantastic. Can’t wait (heh) for async/await to land, and the Actors pattern looks really compelling.</div><div class=""><br class=""></div><div class="">One thought that occurred to me reading through the section of the "async/await" proposal on whether async implies throws:</div><div class=""><br class=""></div><div class="">If ‘async' implies ‘throws' and therefore ‘await' 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" class=""><div style="word-wrap:break-word" class=""><div class=""><br class=""></div><div class=""><font face="Menlo" class="">guard let foo = await? getAFoo() else { … }</font></div></div></blockquote><div class=""><br class=""></div><div class="">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 class=""><br class=""></div></span>try? and try! are quite common from what I've seen.</div></blockquote><div class="gmail_extra"><br class=""></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 class=""></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 class=""></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 class=""></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 class=""></div><div class="gmail_extra">```</div><div class="gmail_extra">// `throws/try`</div><div class="gmail_extra">func foo() -> 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 class=""></div><div class="gmail_extra">}</div><div class="gmail_extra"><br class=""></div><div class="gmail_extra">// `async/await`</div><div class="gmail_extra">func foo() -> 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 class=""></div><div class="gmail_extra">And `try!` is similar to `do/try/catch`.</div><div class="gmail_extra"><br class=""></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 class=""></div><div class="gmail_extra">// `do/try/catch`</div><div class="gmail_extra">do {<br class=""></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 class=""> fatalError()<br class="">}</div><div class="gmail_extra">```</div><div class="gmail_extra"><br class=""></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 class=""></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></div></blockquote><div><br class=""></div>Personally, I think these sources of confusion are a good reason to keep the feature separate.</div><div><br class=""></div><div>The idea of using await! to block a thread is interesting but, as you say, does not fit with the general meaning of ! for logic errors. I think it's fine to just have an API to block waiting for an async operation, and we can choose the name carefully to call out the danger of deadlocks.</div><div><br class=""></div><div>John.</div><div><br class=""><blockquote type="cite" class=""><div class=""><div dir="ltr" class=""><div class="gmail_extra"><br class=""></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 class=""></div><div class="gmail_extra"><div class=""><div class="gmail_signature">--<br class="">Yuta</div></div></div></div>
</div></blockquote></div><br class=""></body></html>