SE-0276: Multi-Pattern Catch Clauses

Bummer. Having no way to access the original error is pretty limiting and usually means I don't use a pattern. This is an existing problem so it may indeed would be a separate proposal, but it does mean it's and incomplete replacement of the pattern pointed to as the motivation since with the catch let error as TaskError; switch error { pattern the cases still have access to error.

compared to...

do {
    try performTask()
} catch TaskError.someFailure(let msg),
        TaskError.anotherFailure(let msg) {
    showMessage(msg)
    // What if it should re-throw?
    // What if logging more info other than `msg` is required?
    // Also, no additional information available during debugging 😬
}

Not really a detraction from the proposal, so still +1 from me, but kind of a bummer I won't be able to justify using it :disappointed:

1 Like

Sidenote...didn't realize emoji get italicized :smile:

4 Likes

What is your evaluation of the proposal?
+1

Is the problem being addressed significant enough to warrant a change to Swift?
Yes

Does this proposal fit well with the feel and direction of Swift?
Yes

How much effort did you put into your review? A glance, a quick reading, or an in-depth study?
I’ve read the proposal and followed the discussion. And I’ve looked at code bases where the error is switched on in catch clauses - just like the proposal mentions. This will be nice for consistency and conciseness.

I am afraid of addition that makes language syntax more divergent for sake of some potential unclear improvement. With such rapid speed of reinventing wheels, soon there will be only remnants of what swift used to be: clear, (mostly) unified syntax.

-1 :worried: @Chris_Lattner3

1 Like

Wouldn’t a change like that be forward compatible with the current implicit error? That seems like any new behavior could be potentially be additive, and the benefit of still having the error but maybe having to cast it inside of the block wouldn’t be overly burdensome. Then at a later time if it implicitly bound to a more specific error type it shouldn’t break any existing code, right?

This reply isn’t terribly constructive. Can you explain why you think having multiple error patterns in a catch clause makes the language less clear than the current situation where you have to nest a switch statement inside the catch? You say that the syntax is “(mostly) unified”, but doesn’t making catch patterns act like other case clauses make the language more unified, not less?

3 Likes

Potentially, depending on the final design. It’s a little too early to say what the exact semantics would be though. I don’t think a follow up proposal to expand implicit error binding would be all that controversial, but it’s mostly orthogonal to this proposal.

  • What is your evaluation of the proposal?

+1, it seems like an obvious extension of the error handling syntax.

  • Is the problem being addressed significant enough to warrant a change to Swift?

Yes, at least as far as it's inline with pattern matching seen elsewhere and enhances an important feature of the language.

  • Does this proposal fit well with the feel and direction of Swift?

Generally yes, though the intersection of previous catch behavior and pattern matching like this, namely around the implicit error value, leaves a sharp edge. However, it looks like this can be dealt with fairly easily.

  • If you have used other languages or libraries with a similar feature, how do you feel that this proposal compares to those?

No.

  • How much effort did you put into your review? A glance, a quick reading, or an in-depth study?

Quick reading of the proposal.

I think that it adds nothing more that 'the other way around' which is not a good thing to do, given that such improvements has lead to nothing but to having obstacles in software development, when you has to consider all special cases in every single place. I believe swift's syntax does not need this particular change.

do {
  try performTask()
} catch let error as TaskError {
  switch error {
  case TaskError.someRecoverableError:
    recover()
  case TaskError.someFailure(let msg):
    showMessage(msg)
  }
}

This code for me is perfectly clear. You perform an action that can potentially go wrong, than if it's true you handle them in the way you need.

do {
  try performTask()
} catch let error {
  <#expression to handle error anyhow you want#>
}
1 Like

I'm ambivalent on this topic. It's hard to imagine that combining two otherwise discrete syntaxes noticeably improving the language. The error handling in Swift already feels convoluted in its bare bones state. There are certainly other improvements like typed throwing that would advance error handling leaps and bounds more than creating a new way to express something you can already express in Swift by just using a switch statement.

Just in case you missed it, the proposal has been accepted: [Accepted] SE-0276: Multi-Pattern Catch Clauses - #2

(edit: I thought it would be a good idea to move the discussion to a separate thread as the proposal has been accepted, but seems like the announcement thread has been locked)

Thanks, I saw :slight_smile:

1 Like

Well, seems like trend had been set and we might expect some bloating in places here and there in the future.