[swift-evolution] Proposal: Allow Type Annotations on Throws
David Owens II
david at owensd.io
Fri Dec 18 10:50:41 CST 2015
> On Dec 18, 2015, at 5:53 AM, Matthew Johnson <matthew at anandabits.com> wrote:
> Thank you for taking the time to continue working on a proposal for typed throws. I agree that this feature is very desirable and appreciate the work you’re doing to bring forward a proposal. I think it’s a great start but also has some room for improvement.
> First, I think it could be strengthened by incorporating some learning from Rust. My impression is that the Rust community is very happy with typed error handling. Adding some detail about their experience would provide a counter-example to those who are concerned about the experience in Java and C++.
I’m not involved in the Rust community so I wouldn’t feel comfortable making claims for them.
> I agree that error types are an important part of an API contract. 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. 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. You might want to take a look at the From mechanism Rust uses to facilitate this. 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).
The From() construct seems like a map(T) -> U problem, but it seems heavily tied into the ability to create sum types. Swift doesn’t have this feature, and that feature is out-of-scope for this proposal. More on this later.
> I would also like to see much more detail on why you think allowing a function to throw multiple error types is problematic. My impression is that you have concerns from a usability point of view. 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.
Sure. There’s no functionality today to auto-generate a sum type in Swift today, and that is what this request really is. If you want to return multiple return types, then you need to do exactly what Rust does and create a sum type that composes the various types of errors. This exposes the same potential fragile API surface as extending enums do. I did call this part out specifically.
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.
> 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. It just says “Java checked exceptions”. I know these have been pretty much universally considered a serious design mistake. My impression is that there are quite a few reasons for that. I don’t have any direct experience with Java and am not familiar with the details. 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. Links would be sufficient if they are focused on answering this particular question.
I guess I should have just specifically called this out in the proposal. It’s not because of “Java checked exceptions”, it’s because nowhere else in the language are types allowed to be essentially annotated in a sum-like fashion. We can’t directly say a function returns an Int or a String. We can’t say a parameter can take an Int or a Double. Similarly, I propose we can’t say a function can return an error A or B.
Thus, the primary reason is about type-system consistency.
Swift already supports a construct to create sum types: associated enums. What it doesn’t allow is the ability to create them in a syntactic shorthand. In this way, my error proposal does the same thing as Rust: multiple return types need to be combined into a single-type - enum.
On to Félix’s comments now!
More information about the swift-evolution