> On Dec 18, 2015, at 9:41 AM, Matthew Johnson <matt...@anandabits.com> wrote:
> 
> 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.

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.

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

That example takes you through many of the options available. In the end, you 
end up at the sum-type for the error:
fn search<P: AsRef<Path>>
         (file_path: &Option<P>, city: &str)
         -> Result<Vec<PopulationCount>, CliError> {
    ...
}
It’s the CliError which is defined as:
enum CliError {
    Io(io::Error),
    Csv(csv::Error),
    NotFound,
}
The From() function essentially allows the try! macro to expand these in a 
nicer way.

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:

enum Combined {
    case IO(String)
    case Number(Int)
}

func simulate(err: Combined) {
    switch err {
    case let Combined.IO(string) where string == "hi": print("only hi!")
    case let Combined.IO(string): print(string)
    case let Combined.Number(value): print(value)
    }
}

simulate(Combined.IO("hi"))
simulate(Combined.IO("io"))
simulate(Combined.Number(9))

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.

Maybe adding this to the proposal would clarify usage?

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

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.

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

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.

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

See above example. Does that address this concern?

-David

_______________________________________________
swift-evolution mailing list
swift-evolution@swift.org
https://lists.swift.org/mailman/listinfo/swift-evolution

Reply via email to