> Am 21.08.2017 um 22:09 schrieb Karim Nassar via swift-evolution > <swift-evolution@swift.org>: > > Thought about it in more depth, and I’m now firmly in the camp of: > ‘throws’/‘try' and ‘async’/‘await' should be orthogonal features. I think the > slight call-site reduction in typed characters ('try await’ vs ‘await’) is > heavily outweighed by the loss of clarity on all the edge cases.
+1 -Thorsten > > —Karim > >> On Aug 21, 2017, at 1:56 PM, John McCall <rjmcc...@apple.com >> <mailto:rjmcc...@apple.com>> wrote: >> >>> >>> On Aug 20, 2017, at 3:56 PM, Yuta Koshizawa <ko...@koherent.org >>> <mailto:ko...@koherent.org>> wrote: >>> >>> 2017-08-21 2:20 GMT+09:00 John McCall via swift-evolution >>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>>: >>>> On Aug 19, 2017, at 7:17 PM, Chris Lattner via swift-evolution >>>> <swift-evolution@swift.org <mailto:swift-evolution@swift.org>> wrote: >>>>> On Aug 19, 2017, at 8:14 AM, Karim Nassar via swift-evolution >>>>> <swift-evolution@swift.org <mailto: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`. >> >> Personally, I think these sources of confusion are a good reason to keep the >> feature separate. >> >> 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. >> >> John. >> >>> >>> 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
_______________________________________________ swift-evolution mailing list swift-evolution@swift.org https://lists.swift.org/mailman/listinfo/swift-evolution