2017-08-21 2:20 GMT+09:00 John McCall via swift-evolution < swift-evolution@swift.org>:
> On Aug 19, 2017, at 7:17 PM, Chris Lattner via swift-evolution < > swift-evolution@swift.org> wrote: > > On Aug 19, 2017, at 8:14 AM, Karim Nassar via swift-evolution < > swift-evolution@swift.org> wrote: > > This looks fantastic. Can’t wait (heh) for async/await to land, and the > Actors pattern looks really compelling. > > One thought that occurred to me reading through the section of the > "async/await" proposal on whether async implies throws: > > 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’ ? > > > guard let foo = await? getAFoo() else { … } > > > 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. > > > try? and try! are quite common from what I've seen. > As analogous to `throws` and `try`, I think we have an option that `await!` means blocking. First, if we introduce something like `do/catch` for `async/await`, I think it should be for blocking. For example: ``` do { return await foo() } block ``` 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`. ``` // `throws/try` func foo() -> Int { do { return try bar() } catch { ... } } // `async/await` func foo() -> Int { do { return await bar() } block } ``` And `try!` is similar to `do/try/catch`. ``` // `try!` let x = try! foo() // uses `x` here // `do/try/catch` do { let x = try foo() // uses `x` here } catch { fatalError() } ``` 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. 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`. 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. -- Yuta
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution