<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=""><br class=""><div><blockquote type="cite" class=""><div class="">On Dec 18, 2015, at 9:03 AM, Félix Cloutier &lt;<a href="mailto:felixcca@yahoo.ca" class="">felixcca@yahoo.ca</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=""><div class="">The biggest problem I have with error handling is that most schemes aren't predictable. I like that Swift's model forces you to reduce the possible errors to a single type, most easily an enum type, because this promotes predictability: your function can fail for no more or no less than what the enum has. This goes hand in hand with forcing try on functions that throw, so that you always know what could go wrong and what has gone wrong.</div><div class=""><br class=""></div><div class="">What I invariably hate about the common exception model and the common error code model is that the error conditions are either theoretically or practically infinite. It makes it hard to determine which errors you can actually trigger, which in turns makes it hard to decide which cases should be handled and which cases should be forwarded, which perpetuates that it's hard to determine which errors you can trigger.</div></div></div></blockquote><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="">Integral error codes are limited, but the limit is far above what human beings can model and consider, and each integral value can be overloaded. Microsoft's HRESULT and Apple's OSStatus are two examples of large and overloaded status codes (see <a href="http://osstatus.com/" class="">osstatus.com</a> for how bad this can get). Luckily, this model is discouraged with Swift.</div></div></div></blockquote><div><br class=""></div><div>+1 to these comments. &nbsp;A finite list of non-polymorphic error types (ideally enums to explicitly declare the cases) has the same advantages of discoverability. &nbsp;It also has the potential advantage that it is would be easier to re-use error types. &nbsp;If this is done carefully it could facilitate improved re-use of error handling code. &nbsp;The potential downside is that it could encourage less thoughtful API contracts where people just add any error type they might trigger to the list. &nbsp;An error translation mechanism similar to From in Rust is probably necessary to mitigate this.</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="">Polymorphic exceptions, on their end, have two major shortfalls: they allow an infinite class of errors to be raised at any point where the call graph isn't entirely static (since developers can subclass the error class), and they encourage errors to be classified by kind instead of by cause.</div></div></div></blockquote><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="">In my opinion, kind-based exception hierarchies are the original sin of exception handling. For a spectacular failure of exception design, look no further than Java's IOException hierarchy. A method that catches an IOException may be dealing with a ClosedChannelException, a MalformedURLException, a UserPrincipalNotFoundException, an UnsupportedEncodingException, or any other of the 31 direct known subclasses (or a subclass of any of these), or any other user subclass. These are all things that can happen during some I/O, but it makes IOException as a catchable type entirely meaningless.</div></div></div></blockquote><div><br class=""></div><div>Agree. &nbsp;This sounds awful.</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="">Unfortunately, it's extremely tempting to categorize exceptions by kind, because object-oriented programming is all about categorizing things by kind. This was just one of the platoon of exception hierarchies that fell down the proverbial slippery slope.</div><div class=""><br class=""></div><div class="">For this reason, I don't like to encourage throwing polymorphic types, and I think that it's a misconception to pretend that having a single type in the throws annotation ensures that the function throws a single type. In my opinion, the fact that it's currently possible but awkward to use polymorphic types as errors is exactly as much support as the feature should receive.</div></div></div></blockquote><div><br class=""></div><div>I agree with most of what you’re stating here. &nbsp;Except that the only type information currently available for throwing functions is that they throw `ErrorType`. &nbsp;It doesn’t get more polymorphic than that!</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 class=""><blockquote type="cite" class=""><div class="">Le 18 déc. 2015 à 08:53:44, Matthew Johnson via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; a écrit :</div><br class="Apple-interchange-newline"><div class=""><span style="font-family: LucidaGrande; 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; float: none; display: inline !important;" class="">David,</span><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;">Thank you for taking the time to continue working on a proposal for typed throws. &nbsp;I agree that this feature is very desirable and appreciate the work you’re doing to bring forward a proposal. &nbsp;I think it’s a great start but also has some room for improvement.</div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;">First, I think it could be strengthened by incorporating some learning from Rust. &nbsp;My impression is that the Rust community is very happy with typed error handling. &nbsp;Adding some detail about their experience would provide a counter-example to those who are concerned about the experience in Java and C++.</div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;">I agree that error types are an important part of an API contract. &nbsp;One of the big hurdles to doing this well is the need to catch errors when all that needs to be done is to wrap and rethrow them. &nbsp;Ideally should not need to do this just to perform a simple type translation to map the underlying error into the type we wish to expose as part of a stable API contract. &nbsp;You might want to take a look at the From mechanism Rust uses to facilitate this. &nbsp;IMO a proposal for typed error handling should address this issue in some way (even if the author determines this mechanism is not necessary or a good design cannot be identified).</div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;">I would also like to see much more detail on why you think allowing a function to throw multiple error types is problematic. &nbsp;My impression is that you have concerns from a usability point of view. &nbsp;I am on the fence here to some degree, but definitely leaning in the direction that allowing a function to throw multiple error types is better. &nbsp;</div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;">The primary reason I lean this way is that it enables more re-use of standard error types. &nbsp;Custom error types for an API often make sense, but not always. &nbsp;I am concerned about the need to create them just because our API contract might reasonably include two or three of the standard error types. &nbsp;Adding new types when they are not necessary introduces complexity and cognitive overhead. &nbsp;It also complicates catching of errors if the new custom type is a two or three case enum that just embeds the underlying error. &nbsp;</div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;">These problems will lead many people to just revert to an untyped throws clause. &nbsp;Objections to typed errors along these lines are common and legitimate. &nbsp;They will arise during review. &nbsp;It is best if you address them in the proposal now in order to focus a review on your solutions. &nbsp;My personal opinion is that allowing multiple error types and including a mechanism to perform automatic wrapping when appropriate would go a long way towards solving them.</div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;">Implementation challenges related to multi-typed errors have been discussed on the list quite a bit already. &nbsp;They would obviously need to be addressed if we go in that direction. &nbsp;I don’t want to downplay those. &nbsp;But I do think we need to try to identify the most usable solution for typed errors that we can first and then focus on implementation details. &nbsp;If the design needs to be modified to accommodate implementation at least we will have a better idea of what we are giving up.</div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;">I am willing to be convinced that a single error type is better than multiple error types but the current proposal does not provide a compelling argument in that direction. &nbsp;It just says “Java checked exceptions”. &nbsp;I know these have been pretty much universally considered a serious design mistake. &nbsp;My impression is that there are quite a few reasons for that. &nbsp;I don’t have any direct experience with Java and am not familiar with the details. &nbsp;If you could elaborate on specifically why you believe allowing multiple error types was a significant contributor to the problem in a manner that indicates that they will be a problem in any language that includes them I would appreciate that. &nbsp;Links would be sufficient if they are focused on answering this particular question. &nbsp;</div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;">I’m looking forward to your feedback on these thoughts.</div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;">Thanks,</div><div class="" style="font-family: LucidaGrande; 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;">Matthew</div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;"><br class=""></div><div class="" style="font-family: LucidaGrande; 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;"><div class=""><blockquote type="cite" class=""><div class="">On Dec 18, 2015, at 1:29 AM, David Owens II via swift-evolution &lt;<a href="mailto:swift-evolution@swift.org" class="">swift-evolution@swift.org</a>&gt; wrote:</div><br class="Apple-interchange-newline"><div class=""><div class="" style="word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-line-break: after-white-space;">This a significantly updated proposal for typed annotations on the `throws` construct. The previous was closed due to not be complete; I believe I’ve addressed all of those concerns.<div class=""><br class=""></div><div class=""><a href="https://github.com/owensd/swift-evolution/blob/master/proposals/allow-type-annotations-on-throw.md" class="">https://github.com/owensd/swift-evolution/blob/master/proposals/allow-type-annotations-on-throw.md</a></div><div class=""><br class=""></div></div></div></blockquote></div></div></div></blockquote></div><br class=""></div></div></div></blockquote></div><br class=""></body></html>