<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 Feb 17, 2017, at 3:45 PM, Joe Groff via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=us-ascii" class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><br class=""><div class=""><blockquote type="cite" class=""><div class="">On Feb 17, 2017, at 11:03 AM, Adrian Zubarev via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>> wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="bloop_markdown" style="font-family: Helvetica, Arial; font-size: 13px; 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-stroke-width: 0px; background-color: rgb(254, 254, 254);"><p style="margin: 15px 0px; -webkit-margin-before: 0px;" class="">I suggest we need to find a way to shorten the list of the possible error types with a the help of<span class="Apple-converted-space"> </span><code style="font-family: Menlo, Consolas, 'Liberation Mono', Courier, monospace; font-size: 10pt; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; background-color: rgb(248, 248, 248); color: inherit; border: 1px solid rgb(234, 234, 234); margin: 0px 2px; padding: 0px 5px; word-break: normal; word-wrap: normal; -webkit-margin-before: 0px;" class="">typeallias</code></p><pre style="margin: 15px 0px; font-family: Menlo, Consolas, 'Liberation Mono', Courier, monospace; font-size: 10pt; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; background-color: rgb(248, 248, 248); color: inherit; border: 1px solid rgb(204, 204, 204); overflow: auto; padding: 4px 8px; word-break: normal; word-wrap: normal;" class=""><code class="swift" style="font-family: Menlo, Consolas, 'Liberation Mono', Courier, monospace; font-size: 10pt; border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; background-color: rgb(248, 248, 248); color: inherit; border: 0px; margin: 0px; padding: 0px; word-break: normal; word-wrap: normal; -webkit-margin-before: 0px;">extension MyError1: Error { ... }
extension MyError2: Error { ... }
extension MyError3: Error { ... }
typealias MyErrors = MyError1 | MyError2 | MyError3
func foo() throws(MyErrors) -> MyResult
func bar<T : Error>(_: () throws(T) -> Void) rethrows(MyErrors, T) -> MyResult
</code></pre></div></div></blockquote>Do you actually need that? Experience in other languages like Rust and Haskell that use Result-based error propagation suggests that a single error type is adequate, and beneficial in many ways. If nothing else, you could `Either` your way to multiple errors if you really needed to.</div><div class=""><br class=""></div><div class="">IMO, if we accept a single error type per function, there could be a simpler model for this. We could say that the `throws` type is a generic parameter of all function types, and it defaults to the uninhabited `Never` type for functions that don't throw.</div><div class=""><br class=""></div><div class="">() -> () == () throws Never -> ()</div><div class="">() throws -> () == () throws Error -> ()</div><div class=""><br class=""></div><div class="">In this model, you'd get many benefits:</div><div class=""><br class=""></div><div class="">- `rethrows` could become first-class, reducing down to just polymorphic `throws`:</div><div class=""><br class=""></div><div class="">func foo(_: () throws -> ()) rethrows // Swift 3</div><div class="">func foo<T: Error>(_: () throws T -> ()) throws T // Swift X</div>func foo<T: Error>(_: () throws T -> ()) throws Either<MyErrors, T><div class=""><br class=""></div><div class="">- Protocols could abstract over error handling; for instance, we could support throwing sequences:</div><div class=""><br class=""></div><div class="">protocol IteratorProtocol {</div><div class=""> associatedtype Element</div><div class=""> associatedtype Error: Swift.Error = Never</div><div class=""><br class=""></div><div class=""> mutating func next() throws Error -> Element?</div><div class="">}</div><div class=""><br class=""></div><div class="">Separate of the type system model, the type *checking* model also deserves thorough consideration. Propagating the effects of possibly multiple error types propagating within a `do` block is much trickier than doing so as a single "throws" or not bit, especially if you want to be able to use type context in `catch` patterns or to implicitly propagate a narrower `throws` type out of the enclosing function.</div></div></div></blockquote><div><br class=""></div><div>I agree with all of this. The correct way to handle functions that throw multiple error types is with a discriminated union (enum) or an existential. </div><div><br class=""></div><div>If we make enums easier to work with (see my manifesto on generalized enums and value subtyping), we also make it easier to address the use case of functions that need to throw several different error types. That is the more general and useful way to address this use case.</div><br class=""><blockquote type="cite" class=""><div class=""><div style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;" class=""><div class=""><br class=""></div><div class="">-Joe</div></div>_______________________________________________<br class="">swift-evolution mailing list<br class=""><a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a><br class="">https://lists.swift.org/mailman/listinfo/swift-evolution<br class=""></div></blockquote></div><br class=""></body></html>