Typed throws

As you do today:

} catch (let e as CatError) {
} catch (let e as SpouseError) {
} catch (let e as KidError) {

or, for the other example, you might as well use:

} catch (let e as RedError) {
// First match, most specific.
} catch (let e as ColoredError) {
// Catch everything else
}

I think it would be fine if you had to catch the “natural sum type” unless you catch all types declared in the throws-list.

With this approach we do not was ease the client part of a typed throws handling, it seems to me like just the same approach as we have today, but somehow those are typed when in practice they are the same as if they weren't.

Also, in the proposal all the subclassing topics are recorded and documented, maybe we missed something, but I think we do not need several typed errors, as it makes the handling and the writing linearly complex, as if you use subclassing with a single typed error that problem is gone.

As of Swift 5.3 thanks to SE-0276 we can now also handle typed errors as

} catch ColorError.red, ColorError.blue {
  // handle these cases
}
2 Likes

They are untyped though (the interface)

That should be corrected in the draft then, as you could handle same type errors in the same catch clause.

I really wish this topic would move forward again. This, together with all the async work being done currently would have been awesome to work with. :+1:

8 Likes

I think until async is not finished it will be hard to work in the compiler without getting breaking changes during the process. Also, I asked in the proposal thread if it is needed an implementation in order to push the document into a review process. Any information is more than welcome.

Friendly ping to @Douglas_Gregor if he has more information about it.

Thank you all.

An implementation PR is required before the review can go ahead: https://github.com/apple/swift-evolution/blob/main/process.md

When you are ready to request a review, a pull request with an implementation is required in addition to your proposal

though the proposal document can still be discussed and reviewed (though not an "official" review like above) here on the forums.

Implementation would be the next step in the process, but imho pitches like this illustrate that the process is flawed:
Creating a PR is a huge investment (especially for someone who is not a regular contributor yet), and you shouldn't be forced to gamble; it should be up to the core team to clearly signal wether an idea has support, or if a proposal has no prospect of being accepted.
The current rules do a good job confining management workload for Core, but I'm convinced that there a ways to achieve that without such high barriers for those willing to contribute.

10 Likes

We were actually three people trying to work on a PR that could implement the basics of the proposal without any great success due to the reasons you mention, poor knowledge of the compiler or how it could be implemented in every layer of it. I want to make the implementation but I have no knowledge enough to push it forward, that's why my question. I would like to see other ways to move this into a prior review before actually implementing this, time invested, knowledge of the approach and lack of time and resources are my main limitation right now.

2 Likes

I was just stumbling over this pitch again wishing for typed throws myself after hearing @torstenlehmann presenting this topic at the CocoaHeads Leipzig meetup.
Since I didn't find any matching posts (searching this topic for "java", "kotlin" and "checked exceptions":

Have you checked why Kotlin does not have checked exceptions?

The mentioned citations provide good arguments not to have typed throws for larger projects, as far as I can tell at the moment.

From The Trouble with Checked Exceptions (Anders Hejlsberg):

"… People don't care. They're not going to handle any of these exceptions."

and because you'd want to have a centralized point to catch exceptions:

"The trouble begins when you start building big systems where you're talking to four or five different subsystems. Each subsystem throws four to ten exceptions. Now, each time you walk up the ladder of aggregation, you have this exponential hierarchy below you of exceptions you have to deal with. You end up having to declare 40 exceptions that you might throw. And once you aggregate that with another subsystem you've got 80 exceptions in your throws clause. It just balloons out of control."

One important motivational case which is independent of the ballooning of Error types are those functions which simply preserve errors unchanged from a lower level (function argument etc.).

Thus I would imagine that a good MVP would be to restrict throws type declarations to one of:
A local generic parameter with only an Error bound, Never, or Error itself.

This would get the syntax in place and allow an API to guarantee that it only propagates errors, not generates new ones or changes their types.

This was our approach, as can be seen in the PR, but it gets actually tricky to get the Never type at the compiler level, as it always gets declared as a nullptr...