> On Dec 18, 2015, at 10:50 AM, David Owens II <[email protected]> wrote:
> 
> 
>> On Dec 18, 2015, at 5:53 AM, Matthew Johnson <[email protected]> wrote:
>> 
>> David,
>> 
>> 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’m not asking for you to speak for them.  But I do think we need to learn from 
communities that are having success with typed error handling.  Your proposal 
would be stronger if it went into detail about how it would avoid the problems 
that have been encountered in other languages.  The experience of Rust could 
help to make that case as it is concrete and not hypothetical.

> 
>> 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.

My understanding is that Rust uses static multi-dispatch to do this.  I don’t 
believe it has anything to do with structural sum types.  Rust error handling 
uses a Result type with a single error case: 
http://doc.rust-lang.org/book/error-handling.html 
<http://doc.rust-lang.org/book/error-handling.html>.

If you don’t believe a mechanism like this is necessary and don’t include one 
in your design it will lead to either a lot of boilerplate or avoidance of 
typed errors (depending on the developer).  I think you should expect a lot of 
complaints about this and I think it will generate a lot of -1 votes for the 
proposal.

> 
>> 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.

How does this create a fragile API surface area?  Adding a new error type to 
the signature would be a breaking change to the API contract.  This is really 
no different than changing the type of error that can be thrown under your 
proposal.

> 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.

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.  IMO it’s pretty important to get the design of typed errors right 
if / when we add them.  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.

I also think typed errors may be one of the more important use cases for 
structural sum types of some kind.  If we are able to show that design problems 
that cannot be solved without them can be solved with them that might influence 
whether they are added or not.  It might also influence when it makes sense to 
add support for typed errors to the language.

> 
>> 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.

That approach would make catch clauses rather clunky by nesting errors inside 
of associated values.  If you’re advocating for this approach do you have any 
ideas on how to streamline syntax for catching them?

Matthew

_______________________________________________
swift-evolution mailing list
[email protected]
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to