<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=""><div class="">Hi David,</div><div class=""><br class=""></div><div class="">I spent a lot of time last night thinking about how my concerns can be addressed without changes to the type system. &nbsp;I also spent some time working through some concrete examples this morning. &nbsp;This has helped narrow my concerns considerably.</div><div class=""><br class=""></div><div class="">I am going to suggest one addition to the proposal at the end. &nbsp;If you’re willing to incorporate that I will be pretty happy with what we can accomplish without any changes to the type system.</div><div class=""><br class=""></div><div class="">First, consider the case where there are some common errors which a library may throw in different places. &nbsp;These are considered to be part of the API contract. &nbsp;Some library functions may throw either common error depending on the code path taken. &nbsp;</div><div class=""><br class=""></div><div class="">Your proposal suggests we should fall back to throwing ErrorType in that case. &nbsp;This is not really a good solution in my mind. &nbsp;</div><div class=""><br class=""></div><div class="">A library should be able to have a family of error types it publishes in its API contract and some functions should be able to throw more than one. &nbsp;As you suggest, rather than a structural sum type we can manually create a sum type to do this. &nbsp;</div><div class=""><br class=""></div><div class="">I had two concerns about this. &nbsp;The first and most important was in the verbosity of catching the nested errors. &nbsp;Here’s an example:</div><div class=""><br class=""></div><div class="">enum&nbsp;CommonOne:&nbsp;ErrorType&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;One<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;Two<br class="">}<br class="">enum&nbsp;CommonTwo:ErrorType&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;One<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;Two<br class="">}<br class="">enum&nbsp;Both:&nbsp;ErrorType&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;One(CommonOne)<br class="">&nbsp; &nbsp;&nbsp;case&nbsp;Two(CommonTwo)<br class="">}</div><div class=""><br class=""></div><div class="">I was concerned that we would need to do something like this involving some verbose and nasty nesting, etc:</div><div class=""><br class=""></div><div class="">func functionThatThrowsBoth() throws Both { … }</div><div class=""><br class=""></div><div class="">do&nbsp;{<br class="">&nbsp; &nbsp; try functionThatThrowsBoth()<br class="">}<br class="">catch .One(let inner) {</div><div class="">&nbsp; &nbsp; switch inner {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; case .one: ...</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; case .two: ...</div><div class="">&nbsp; &nbsp; }</div><div class="">}</div><div class=""><div class="">catch .Two(let inner) {</div><div class="">&nbsp; &nbsp; switch inner {</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; case .one: ...</div><div class="">&nbsp; &nbsp; &nbsp; &nbsp; case .two: ...</div><div class="">&nbsp; &nbsp; }</div><div class="">}</div></div><div class=""><br class=""></div><div class="">As it turns out, I am still getting familiar with the power of nested pattern matching and this was an unfounded concern. &nbsp;This is great! &nbsp;We can actually do this:</div><div class=""><br class=""></div><div class="">do {<br class="">&nbsp; &nbsp; try functionThatThrowsBoth()<br class="">}<br class="">catch .One(.One) { ...&nbsp;}<br class="">catch .One(.Two) { ...&nbsp;}<br class="">catch .Two(.One) { ...&nbsp;}<br class="">catch .Two(.Two) { ...&nbsp;}</div><div class=""><br class=""></div><div class="">(note: this works today if you include a Both prefix in the cases which will be unnecessary with a typed error)</div><div class=""><br class=""></div><div class="">That is great! &nbsp;I have no concerns about this syntax for catching nested errors. &nbsp;This covers use cases that need to throw “multiple” error types pretty well. &nbsp;There are probably some edge cases where a structural sum type would be more convenient but I think they would be rare and am not concerned about them.</div><div class=""><br class=""></div><div class="">I would also like to comment that there are some interesting related ideas for enhancing enums in the "<font face="Helvetica Neue" class="">[Pitch] Use enums as enum underlying types” thread. &nbsp;They don’t directly impact the proposal but could make such use cases even more convenient if they are pursued independently.</font></div><div class=""><br class=""></div><div class="">The other concern I have is still valid, but I think a relatively straightforward solution is possible.</div><div class=""><br class=""></div><div class="">Continuing with the previous example, let’s look at the implementation of `functionThatThrowsBoth`:</div><div class=""><br class=""></div><div class="">func&nbsp;throwsInnerOne()&nbsp;throws InnerOne&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;throw&nbsp;InnerOne.One<br class="">}<br class=""><br class="">func&nbsp;throwsInnerTwo()&nbsp;throws&nbsp;InnerTwo {<br class="">&nbsp; &nbsp;&nbsp;throw&nbsp;InnerTwo.Two<br class="">}</div><div class=""><br class=""></div><div class="">func&nbsp;functionThatThrowsBoth(_&nbsp;whichError:&nbsp;Bool)&nbsp;throws Both&nbsp;{<br class="">&nbsp; &nbsp;&nbsp;do&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;if&nbsp;whichError {<br class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;try&nbsp;throwsInnerOne()<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}&nbsp;else&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp;try&nbsp;throwsInnerTwo()<br class="">&nbsp; &nbsp; &nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;}<br class="">&nbsp; &nbsp;&nbsp;catch&nbsp;let&nbsp;inner&nbsp;as&nbsp;InnerOne&nbsp;{&nbsp;throw&nbsp;Both.One(inner) }<br class="">&nbsp; &nbsp;&nbsp;catch&nbsp;let&nbsp;inner&nbsp;as&nbsp;InnerTwo&nbsp;{&nbsp;throw&nbsp;Both.Two(inner) }<br class="">}<br class=""><br class=""></div><div class="">The implementation is dominated by the concern of wrapping the error. &nbsp;This is pretty gross. &nbsp;This problem exists even if we are not wrapping the error, but rather <b class="">translating</b>&nbsp;the error from the underlying error type into the error type we are publishing in our API contract. &nbsp;</div><div class=""><br class=""></div><div class="">Here is an example where we are not wrapping the error, but translating it:</div><div class=""><br class=""></div><div class="">func functionThatCallsUnderlingyingThrows(_&nbsp;whichError:&nbsp;Bool)&nbsp;throws MyPublishedError&nbsp;{<br class="">&nbsp; &nbsp; do&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp; try funcThatThrowsAnErrorThatMustBeTranslatedIntoMyPublishedError()<br class="">&nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; // catching logic that eventually throws MyPublishedErrorSomehow</div><div class="">}</div><div class=""><br class=""></div><div class="">The best we can do is to create a translation function or initializer:</div><div class=""><br class=""></div><div class="">enum MyPublishedError: ErrorType {</div><div class="">&nbsp; &nbsp; init(_ error: UnderlyingError) { … }</div><div class="">}</div><div class=""><br class=""></div><div class=""><div class="">func functionThatCallsUnderlingyingThrows(_&nbsp;whichError:&nbsp;Bool)&nbsp;throws MyPublishedError&nbsp;{<br class="">&nbsp; &nbsp; do&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp; try funcThatThrowsAnErrorThatMustBeTranslatedIntoMyPublishedError()<br class="">&nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; catch let error as UnderlyingError { throw MyPublishedError(error) }</div><div class="">}</div></div><div class=""><br class=""></div><div class="">This is better as it removes the logic from the function itself. &nbsp;But it’s still not great as it introduces a lot of boilerplate everywhere we need to translate and / or wrap errors. &nbsp;The boilerplate also grows for each underlying error we need to translate:</div><div class=""><br class=""></div><div class=""><div class="">func functionThatCallsUnderlingyingThrows(_&nbsp;whichError:&nbsp;Bool)&nbsp;throws MyPublishedError&nbsp;{<br class="">&nbsp; &nbsp; do&nbsp;{<br class="">&nbsp; &nbsp; &nbsp; &nbsp; // bunch of stuff throwing several different errors<br class="">&nbsp; &nbsp; }</div><div class="">&nbsp; &nbsp; catch let error as UnderlyingError { throw MyPublishedError(error) }</div><div class="">&nbsp; &nbsp; catch let error as OtherUnderlyingError { throw MyPublishedError(error) }</div><div class="">&nbsp; &nbsp; // more catch clauses until we have covered every possible error type thrown by the body</div><div class="">&nbsp; &nbsp; // hopefully the compiler wouldn’t require a default clause here but it probably would</div><div class="">}</div></div><div class=""><br class=""></div><div class="">This is the problem that `From` addresses in Rust. &nbsp;Swift is not Rust and our solution will look different. &nbsp;The point is that this <b class="">is</b>&nbsp;a problem and it can and has been solved.</div><div class=""><br class=""></div><div class="">My suggestion is that we should allow implicit conversion during error propagation. &nbsp;If the published error type has one and only one non-failable, non-throwing initializer that takes a single argument of the type that is thrown (including enum case initializers with a single associated value of the thrown type) that initializer is used to implicitly convert to the published error type. &nbsp;This conversion could be accomplished by synthesizing the necessary boilerplate or by some other means.</div><div class=""><br class=""></div><div class="">Now we have:</div><div class=""><br class=""></div><div class="">func functionThatCallsUnderlingyingThrows(_ whichError: Bool) throws MyPublishedError {<br class="">&nbsp; &nbsp; &nbsp; &nbsp; try funcThatThrowsAnErrorThatMustBeTranslatedIntoMyPublishedError()<br class="">}</div><div class=""><br class=""></div><div class="">This looks as it should. &nbsp;We don’t pay a price of boilerplate for carefully designing the errors we expose in our API contract. &nbsp;This also handles automatic wrapping of errors where that is appropriate.</div><div class=""><br class=""></div><div class="">I don’t suggest implicit conversion lightly. &nbsp;I generally hate implicit conversions. &nbsp;But I think it makes a lot of sense here. &nbsp;It keeps concerns separate and removes boilerplate that distracts from the logic at hand, thus vastly improving readability. &nbsp;It is also likely to help minimize code impact when implementation details change and we need to modify how we are translating errors into the contract we expose.</div><div class=""><br class=""></div><div class="">If we don’t support the implicit conversion there are three paths that can be taken by developers. &nbsp;None of them are great and we will have three camps with different preference:</div><div class=""><br class=""></div><div class="">1. Just stick to untyped errors. &nbsp;I think there are some pretty smart people who think this will be a common practice even if we have support for typed errors in the language.</div><div class="">2. Allow underlying errors to flow through (when there is only a single underlying error type). &nbsp;This is brittle and I know you are of the opinion that it is a bad idea. &nbsp;I agree.</div><div class="">3. Write the boilerplate manually. &nbsp;This is annoying and is a significant barrier to clarity and readability.</div><div class=""><br class=""></div><div class="">I hope you will like the idea of implicit conversion during error propagation enough to add it to your proposal. &nbsp;With it I will be an enthusiastic supporter. &nbsp;It will help to establish good practices in the community for using typed errors in a robust and thoughtful way.</div><div class=""><br class=""></div><div class="">Without implicit error conversion I will still support the proposal but would plan to write a follow on proposal introducing the much needed (IMO) implicit conversion during error propagation. &nbsp;I would also expect opposition to the proposal during review from people concerned about one or more of the above listed options for dealing with error translation.</div><div class=""><br class=""></div><div class="">I think the idea of restricting typed errors to structs, enums, NSError, and final classes that has come up is a good one. &nbsp;It might be worth considering going further than that and restrict it to only enums and NSError. &nbsp;One of the biggest issues I have encountered with error handling during my career is that all too often the possible error cases are quite poorly documented. &nbsp;We have to allow NSError for Cocoa interop, but aside from the error types should really be enums IMO as they make it very clear what cases might need to be handled.</div><div class=""><br class=""></div><div class="">I want to thank you again for putting this proposal together and taking the time to consider and respond to feedback. &nbsp;Typed errors will be a significant step forward for Swift and I am looking forward to it. &nbsp;</div><div class=""><br class=""></div><div class="">Matthew</div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><div class=""><br class=""></div><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 18, 2015, at 12:36 PM, David Owens II &lt;<a href="mailto:david@owensd.io" class="">david@owensd.io</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><meta http-equiv="Content-Type" content="text/html charset=utf-8" 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 Dec 18, 2015, at 9:41 AM, Matthew Johnson &lt;<a href="mailto:matthew@anandabits.com" class="">matthew@anandabits.com</a>&gt; wrote:</div><div class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class=""><div class=""><br class=""></div><div class="">I’m not asking for you to speak for them. &nbsp;But I do think we need to learn from communities that are having success with typed error handling. &nbsp;Your proposal would be stronger if it went into detail about how it would avoid the problems that have been encountered in other languages. &nbsp;The experience of Rust could help to make that case as it is concrete and not hypothetical.</div></div></div></blockquote><div class=""><br class=""></div><div class="">Sure, it could. It’s also anecdotal. It’s not necessarily true that something that works well in one context works well in another. It’s good to note that typed errors are wholly considered bad, but I’m not sure how much further we need to go then that. If you have specifics, then I could probably add them as an addendum to the proposal.</div><br class=""><blockquote type="cite" class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class="">My understanding is that Rust uses static multi-dispatch to do this. &nbsp;I don’t believe it has anything to do with structural sum types. &nbsp;Rust error handling uses a Result type with a single error case:&nbsp;<a href="http://doc.rust-lang.org/book/error-handling.html" class="">http://doc.rust-lang.org/book/error-handling.html</a>.</div></blockquote><div class=""><br class=""></div><div class="">That example takes you through many of the options available. In the end, you end up at the sum-type for the error:</div><div class=""><pre class="rust-example-rendered rust" style="box-sizing: border-box; font-family: 'Source Code Pro', Menlo, Monaco, Consolas, 'DejaVu Sans Mono', monospace; word-wrap: break-word; border: 0px; white-space: pre-wrap; padding: 11px; margin-top: 20px; margin-bottom: 20px; font-size: 14px; word-break: break-all; overflow: auto; line-height: 1.45; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; position: relative;"><span style="color: rgb(51, 51, 51);" class=""><span class="kw" style="box-sizing: border-box; color: rgb(137, 89, 168);">fn</span> <span class="ident" style="box-sizing: border-box;">search</span><span class="op" style="box-sizing: border-box;">&lt;</span><span class="ident" style="box-sizing: border-box;">P</span>: <span class="ident" style="box-sizing: border-box;">AsRef</span><span class="op" style="box-sizing: border-box;">&lt;</span><span class="ident" style="box-sizing: border-box;">Path</span><span class="op" style="box-sizing: border-box;">&gt;&gt;</span>
         (<span class="ident" style="box-sizing: border-box;">file_path</span>: <span class="kw-2" style="box-sizing: border-box; color: rgb(66, 113, 174);">&amp;</span><span class="prelude-ty" style="box-sizing: border-box; color: rgb(66, 113, 174);">Option</span><span class="op" style="box-sizing: border-box;">&lt;</span><span class="ident" style="box-sizing: border-box;">P</span><span class="op" style="box-sizing: border-box;">&gt;</span>, <span class="ident" style="box-sizing: border-box;">city</span>: <span class="kw-2" style="box-sizing: border-box; color: rgb(66, 113, 174);">&amp;</span><span class="ident" style="box-sizing: border-box;">str</span>)
         <span class="op" style="box-sizing: border-box;">-&gt;</span> <span class="prelude-ty" style="box-sizing: border-box; color: rgb(66, 113, 174);">Result</span><span class="op" style="box-sizing: border-box;">&lt;</span><span class="ident" style="box-sizing: border-box;">Vec</span><span class="op" style="box-sizing: border-box;">&lt;</span><span class="ident" style="box-sizing: border-box;">PopulationCount</span><span class="op" style="box-sizing: border-box;">&gt;</span>, <span class="ident" style="box-sizing: border-box;">CliError</span><span class="op" style="box-sizing: border-box;">&gt;</span> {
    </span><font color="#8959a8" class="">...</font><font color="#333333" class="">
}</font></pre><div class="">It’s the CliError which is defined as:</div><div class=""><pre class="rust-example-rendered rust" style="box-sizing: border-box; font-family: 'Source Code Pro', Menlo, Monaco, Consolas, 'DejaVu Sans Mono', monospace; word-wrap: break-word; border: 0px; white-space: pre-wrap; padding: 11px; margin-top: 20px; margin-bottom: 20px; font-size: 14px; word-break: break-all; overflow: auto; line-height: 1.45; background-color: rgb(247, 247, 247); border-top-left-radius: 3px; border-top-right-radius: 3px; border-bottom-right-radius: 3px; border-bottom-left-radius: 3px; position: relative; color: rgb(51, 51, 51);"><span class="kw" style="box-sizing: border-box; color: rgb(137, 89, 168);">enum</span> <span class="ident" style="box-sizing: border-box;">CliError</span> {
    <span class="ident" style="box-sizing: border-box;">Io</span>(<span class="ident" style="box-sizing: border-box;">io</span>::<span class="ident" style="box-sizing: border-box;">Error</span>),
    <span class="ident" style="box-sizing: border-box;">Csv</span>(<span class="ident" style="box-sizing: border-box;">csv</span>::<span class="ident" style="box-sizing: border-box;">Error</span>),
    <span class="ident" style="box-sizing: border-box;">NotFound</span>,
}</pre></div><div class="">The From() function essentially allows the <b class="">try!</b>&nbsp;macro to expand these in a nicer way.</div><div class=""><br class=""></div><div class="">So back to the proposal, one of the key things is to promote the `error` constant throughout the catch-clauses. This means that we can already leverage Swift’s pattern matching to solve this problem:</div><div class=""><br class=""></div></div></div><blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;" class=""><div class=""><div class=""><div class=""><font face="Menlo" class="">enum&nbsp;Combined {</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;case&nbsp;IO(String)</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;case&nbsp;Number(Int)</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">}</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class=""><br class=""></font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">func&nbsp;simulate(err:&nbsp;Combined) {</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;switch&nbsp;err {</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;case&nbsp;let&nbsp;Combined.IO(string)&nbsp;where&nbsp;string ==&nbsp;"hi":&nbsp;print("only hi!")</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;case&nbsp;let&nbsp;Combined.IO(string):&nbsp;print(string)</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;case&nbsp;let&nbsp;Combined.Number(value):&nbsp;print(value)</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">&nbsp; &nbsp;&nbsp;}</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">}</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class=""><br class=""></font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">simulate(Combined.IO("hi"))</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">simulate(Combined.IO("io"))</font></div></div></div><div class=""><div class=""><div class=""><font face="Menlo" class="">simulate(Combined.Number(9))</font></div></div></div></blockquote><div class=""><div class=""><div class=""><br class=""></div><div class="">It’s not hard to use Swift’s pattern matching to extract out the inner information on an associated value enum and white the case/catch clauses. So unless I’m missing something, I think Swift already provides a good mechanism to do what you’re asking for, with the caveat that the `error` constant is promoted to be usable in the catch-clauses similar to how the switch-statements work.</div><div class=""><br class=""></div><div class="">Maybe adding this to the proposal would clarify usage?</div><div class=""><br class=""></div></div><blockquote type="cite" class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class=""><div class="">How does this create a fragile API surface area? &nbsp;Adding a new error type to the signature would be a breaking change to the API contract. &nbsp;This is really no different than changing the type of error that can be thrown under your proposal.</div></div></blockquote><div class=""><br class=""></div><div class="">It’s the same fragility that enums create; this was covered in the criticisms section. The likelihood of adding additional error cases is much greater than a change that would completely change the type of the error.</div><br class=""><blockquote type="cite" class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class=""><br class=""><blockquote type="cite" class=""><div class="">I see this functionality as a general limitation in the language. For example, errors are not the only context where you may want to return a type of A, B, or C. There have been other proposals on how we might do that in Swift. If and when it was solved in the general case for type parameters, I can’t foresee a compelling reason why it wouldn’t work in this context as well.<br class=""></div></blockquote><div class=""><br class=""></div><div class="">That makes sense in some ways, but I don’t think it’s unreasonable to ask for some analysis of whether a better design for typed errors would be possible if we had them. &nbsp;IMO it’s pretty important to get the design of typed errors right if / when we add them. &nbsp;If we don’t it will be considered a major mistake and will lead to a lot of less than desirable outcomes down the road.</div><div class=""><br class=""></div><div class="">I also think typed errors may be one of the more important use cases for structural sum types of some kind. &nbsp;If we are able to show that design problems that<span class="Apple-converted-space">&nbsp;</span><b class="">cannot</b><span class="Apple-converted-space">&nbsp;</span>be solved without them<span class="Apple-converted-space">&nbsp;</span><b class="">can</b><span class="Apple-converted-space">&nbsp;</span>be solved with them that might influence whether they are added or not. &nbsp;It might also influence<span class="Apple-converted-space">&nbsp;</span><b class="">when</b>&nbsp;it makes sense to add support for typed errors to the language.</div></div></blockquote><div class=""><br class=""></div><div class="">The problem can be solved without implicitly generated sum types though. The design of typed errors, as proposed, is to be consistent with the Swift type system today. Regardless, I’ve added a response in the “cirticisms” section that hopefully addresses this in some manner - basically, yes it would be helpful, but out of scope for this proposal.</div><br class=""><blockquote type="cite" class=""><div style="font-family: Helvetica; font-size: 12px; font-style: normal; font-variant: 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;" class="">That approach would make catch clauses rather clunky by nesting errors inside of associated values. &nbsp;If you’re advocating for this approach do you have any ideas on how to streamline syntax for catching them?</div></blockquote><br class=""></div><div class="">See above example. Does that address this concern?</div><div class=""><br class=""></div><div class="">-David</div><br class=""></div></div></blockquote></div><br class=""></body></html>