<div>Here we go again... -1</div><div><br><div class="gmail_quote"><div>On Fri, 17 Feb 2017 at 23:52 Matthew Johnson via swift-evolution <<a href="mailto:swift-evolution@swift.org">swift-evolution@swift.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Feb 17, 2017, at 3:45 PM, Joe Groff via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="m_-2483752349479585002Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><br class="gmail_msg"><div class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg">On Feb 17, 2017, at 11:03 AM, Adrian Zubarev via swift-evolution <<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a>> wrote:</div><br class="m_-2483752349479585002Apple-interchange-newline gmail_msg"><div class="gmail_msg"><div class="m_-2483752349479585002bloop_markdown gmail_msg" style="font-family:Helvetica,Arial;font-size:13px;font-style:normal;font-variant-caps:normal;font-weight:normal;letter-spacing:normal;text-align:start;text-indent:0px;text-transform:none;white-space:normal;word-spacing:0px;background-color:rgb(254,254,254)"><p style="margin:15px 0px" class="gmail_msg">I suggest we need to find a way to shorten the list of the possible error types with a the help of<span class="m_-2483752349479585002Apple-converted-space gmail_msg"> </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" class="gmail_msg">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="gmail_msg"><code class="m_-2483752349479585002swift gmail_msg" 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">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="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">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="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">() -> () == () throws Never -> ()</div><div class="gmail_msg">() throws -> () == () throws Error -> ()</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">In this model, you'd get many benefits:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">- `rethrows` could become first-class, reducing down to just polymorphic `throws`:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">func foo(_: () throws -> ()) rethrows // Swift 3</div><div class="gmail_msg">func foo<T: Error>(_: () throws T -> ()) throws T // Swift X</div>func foo<T: Error>(_: () throws T -> ()) throws Either<MyErrors, T><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">- Protocols could abstract over error handling; for instance, we could support throwing sequences:</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">protocol IteratorProtocol {</div><div class="gmail_msg"> associatedtype Element</div><div class="gmail_msg"> associatedtype Error: Swift.Error = Never</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg"> mutating func next() throws Error -> Element?</div><div class="gmail_msg">}</div><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">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 class="gmail_msg"><br class="gmail_msg"></div></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><div class="gmail_msg">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 class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">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></div></div><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"><blockquote type="cite" class="gmail_msg"><div class="gmail_msg"><div style="word-wrap:break-word" class="gmail_msg"><div class="gmail_msg"><br class="gmail_msg"></div><div class="gmail_msg">-Joe</div></div>_______________________________________________<br class="gmail_msg">swift-evolution mailing list<br class="gmail_msg"><a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg"><a href="https://lists.swift.org/mailman/listinfo/swift-evolution" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg"></div></blockquote></div></div>_______________________________________________<br class="gmail_msg">
swift-evolution mailing list<br class="gmail_msg">
<a href="mailto:swift-evolution@swift.org" class="gmail_msg" target="_blank">swift-evolution@swift.org</a><br class="gmail_msg">
<a href="https://lists.swift.org/mailman/listinfo/swift-evolution" rel="noreferrer" class="gmail_msg" target="_blank">https://lists.swift.org/mailman/listinfo/swift-evolution</a><br class="gmail_msg">
</blockquote></div></div>