# New syntax suggestion: catch with type specs

**URL:** https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840
**Category:** Internals & Design
**Tags:** exception
**Created:** [July 20, 2023, 1:51pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840 "2023-07-20T13:51:14Z")
**Posts on this page:** 20
**Page:** 1

<div class="post-metadata">

### Author: ![HanD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hand/32/213908_2.png) [@HanD](https://discourse.julialang.org/u/HanD)
#### Post date: [July 20, 2023, 1:51pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/1 "2023-07-20T13:51:15Z")

</div>

Hello!

When using exceptions and try-catch blocks, it’s very common to handle some specific types of exceptions, and propagate everything else. Here’s how this is usually done:

```julia
try
    # body with potential exceptions
catch e
    if e isa AssertionError
        # handle assertion errors here
    elseif e isa InexactError
        # handle conversion errors here
    else
        rethrow() # everything else is passed on
    end
end

```

For me (and possibly others with some background in functional programming, like myself), this seems a bit cumbersome. There _must_ be a way to be able to write this in a nicer, more concise format, without `if`s. I can, for example, introduce a helper function using type dispatch:

```julia
handle_error(e::AssertionError) = nothing # handle assertion errors here
handle_error(::InexactError) = nothing # handle conversion errors here
handle_error(_) = rethrow()

try
    # body with potential exceptions
catch e
    handle_error(e)
end

```

No more ifs, but now the handling code is somewhat separated from the location of the error. If I follow this thought, the following notation comes to my mind:

```julia
try
    # body with potential exceptions
catch e::AssertionError
    # handle assertion errors here
catch ::InexactError # note the missing variable
    # handle conversion errors here
end
# every other error is propagated (uncaught) implicitly

```

This could be pure syntactic sugar, of course, resolving to either of the two forms above. But it would make the code so much clearer, IMHO!

I tried to find a conversation on this topic, but I couldn’t find any (except for [this ancient one](https://discourse.julialang.org/t/catching-exceptions-by-type/5690)), which took me by surprise.

So, WDYT?

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [July 20, 2023, 6:03pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/2 "2023-07-20T18:03:00Z")

</div>

I really like this, but I also seem to remember that this exact design was discussed several years ago. I think it was put on ice as “not important enough”, or something like that.

I think the suggestion is great, but I also miss a `switch/case` (not macro-based), so…

---

<div class="post-metadata">

### Author: ![dylanxyz](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dylanxyz/32/36646_2.png) [@dylanxyz](https://discourse.julialang.org/u/dylanxyz)
#### Post date: [July 20, 2023, 6:16pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/3 "2023-07-20T18:16:05Z")

</div>

I think it would be trivial to implement this feature if Julia had built in pattern matching.

---

<div class="post-metadata">

### Author: ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)
#### Post date: [July 20, 2023, 7:52pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/4 "2023-07-20T19:52:43Z")

</div>

This is how Python works, and it’s one of the (very few) things I miss when working in Julia.

---

<div class="post-metadata">

### Author: ![stevengj](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/stevengj/32/71_2.png) [@stevengj](https://discourse.julialang.org/u/stevengj)
#### Post date: [July 20, 2023, 8:21pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/5 "2023-07-20T20:21:12Z")

</div>

> [@DNF](#):
>
> I really like this, but I also seem to remember that this exact design was discussed several years ago

> <https://github.com/JuliaLang/julia/issues/23418>
>
> A la
> \`\`\`julia
> try
> foo()
> catch e::ArgumentError
> # hey, I know how to… recover from an ArgumentError!
> catch e::AssertionError
> # I also know how to recover from an AssertionError!
> catch e
> # hmmm, anything else is probably fatal
> rethrow(e)
> end
> \`\`\`
> I know there have been (hotly debated) grand visions of error-handling laid out in #7026 and #15514, but as far as julia 1.0, I think we should at least support catching specific errors. My latest methodology for error-handling goes something like:
> \- Be aware of all possible exceptions thrown by your code and which methods throw them
> \- For each method that might throw, and for each different exception type
> - Decide if there's some kind of recoverable action due to that specific exception type (retry, clean something up & try plan B, etc.)
> - If there's no possibility to recover, we need to rethrow, but possibly as a new exception type with additional context info from where I'm try-catching
> \- Clearly document the types of exceptions that can be thrown from my own methods; what and why each is thrown
> 
> The only issue w/ this approach is I end up w/ code like:
> \`\`\`julia
> try
> foo()
> catch e
> typeof(e) \<: ArgumentError && recover\_from\_argumenterror() # hey, I know how to recover from an ArgumentError!
> typeof(e) \<: AssertionError && recover\_from\_assertionerror() # I also know how to recover from an AssertionError!
> # hmmm, anything else is probably fatal
> rethrow(e)
> end
> \`\`\`
> which is decidedly less pleasant. I feel like having just a little extra syntax could go a long way to making error-handling feel a little more grown up in julia.
> 
> Any idea on how hard this would be? Where to start looking to implement?

and even earlier:

> <https://github.com/JuliaLang/julia/issues/1075>
>
> One ought to be able to write something like this:
> 
> \`\`\` julia
> try f()
> catch e::N…oMethodError
> # handle no method error
> catch e::SomeOtherError
> # handle some other error
> catch e
> # handle any thrown object
> end
> \`\`\`
> 
> Although it needn't actually be implemented by creating a generic function, this should probably emulate the behavior of dispatch, implying that clause order doesn't matter.

TLDR: it was rejected in 2012 since `rethrow()` is semantically sufficient (this is just syntactic sugar), but in 2022 @StefanKarpinski is at least vaguely supportive. But someone needs to submit the PR, which would involve:

1. Changing the parser to parse this syntax
2. Changing the lowering to lower this syntax to a sequence of `if … rethrow() …` statements.

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [July 20, 2023, 8:34pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/6 "2023-07-20T20:34:51Z")

</div>

Yeah, that’s it.

> [@stevengj](#):
>
> TLDR: it was rejected in 2012 since `rethrow()` is semantically sufficient (this is just syntactic sugar),

Yes, and the same goes for `switch/case`. It’s unnecessary, just much _nicer_.

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [July 20, 2023, 8:40pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/7 "2023-07-20T20:40:24Z")

</div>

I am opposed to this change because it encourages the use of exceptions for expected errors. IMO exceptions should be used for unexpected errors, and another system should be introduced for producing and handling failure values. Python uses exceptions for control flow; I don’t think Julia should.

Meanwhile `switch`/`case` is a primitive implementation of pattern matching, which has been implemented much more generally with [`@match`](https://thautwarm.github.io/MLStyle.jl/latest/syntax/pattern.html).

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [July 20, 2023, 9:16pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/8 "2023-07-20T21:16:18Z")

</div>

For my use cases `@match` is overpowered and lacks the single interesting quality of `switch/case`, which is syntactical convenience. I can just as well use `if/elseif/elseif` then.

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [July 20, 2023, 9:29pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/9 "2023-07-20T21:29:11Z")

</div>

What is the proposed switch/case syntax?

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [July 20, 2023, 9:30pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/10 "2023-07-20T21:30:58Z")

</div>

I don’t have one. I like Matlab’s, except it’s a shame to need two reserved keywords.

---

<div class="post-metadata">

### Author: ![jar1](https://avatars.discourse-cdn.com/v4/letter/j/c0e974/32.png) [@jar1](https://discourse.julialang.org/u/jar1)
#### Post date: [July 20, 2023, 9:39pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/11 "2023-07-20T21:39:21Z")

</div>

[Matlab](https://www.mathworks.com/help/matlab/ref/switch.html)

```julia
switch n
    case -1
        disp('negative one')
    case 0
        disp('zero')
    case 1
        disp('positive one')
    otherwise
        disp('other value')
end

```

[MLStyle](https://thautwarm.github.io/MLStyle.jl/latest/syntax/pattern.html)

```julia
@match n begin
  -1 => display("negative one")
   0 => display("zero")
   1 => display("positive one")
   _ => display("other value")
end

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [July 21, 2023, 4:24am UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/12 "2023-07-21T04:24:49Z")

</div>

I prefer the former, especially when each case has multiple lines of code.

---

<div class="post-metadata">

### Author: ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)
#### Post date: [July 21, 2023, 4:50am UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/13 "2023-07-21T04:50:44Z")

</div>

I agree with you in principle, but the reality is that, without an Option Type or some other integrated Error Type system, a lot of code does throw and need to be caught. I even saw a discussion here not that long ago about the performance of checking `hasmethod` vs just running the function and catching the `MethodError` and the latter was better.

As a 2.0 design question, moving to unwrapping with a match makes a lot of sense, but as it stands, it would be really nice to unpack errors with a switch.

---

<div class="post-metadata">

### Author: ![jules](https://avatars.discourse-cdn.com/v4/letter/j/41988e/32.png) [@jules](https://discourse.julialang.org/u/jules)
#### Post date: [July 21, 2023, 5:16am UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/14 "2023-07-21T05:16:05Z")

</div>

I guess you could get close with a macro using `if else` blocks?

Something like

```julia
@switch n if -1
      println("negative one")
  elseif 0
      println("zero")
  elseif 1
      println("positive one")
  else
      println("other value")
end

```

---

<div class="post-metadata">

### Author: ![DNF](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/dnf/32/10191_2.png) [@DNF](https://discourse.julialang.org/u/DNF)
#### Post date: [July 21, 2023, 5:25am UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/15 "2023-07-21T05:25:03Z")

</div>

Yeah, that’s a bit better.

---

<div class="post-metadata">

### Author: ![HanD](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/hand/32/213908_2.png) [@HanD](https://discourse.julialang.org/u/HanD)
#### Post date: [July 21, 2023, 6:46am UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/16 "2023-07-21T06:46:00Z")

</div>

> [@dylanxyz](#):
>
> I think it would be trivial to implement this feature if Julia had built in pattern matching.

True, but id doesn’t. So I deliberately avoided mentioning pattern matching, and stuck to a construct that is fundamental to Julia: type based dispatch.

> [@jar1](#):
>
> I am opposed to this change because it encourages the use of exceptions for expected errors. IMO exceptions should be used for unexpected errors, and another system should be introduced for producing and handling failure values. Python uses exceptions for control flow; I don’t think Julia should.

This would be an interesting topic to debate. I tend to disagree with you. First, if anything encourages the use of exceptions for expected errors it’s the library functions that signal errors using exceptions (such as missing files). Second, it is often the case that certain types of errors need to be handled as and where they occur (and in this case, I agree with you, using return values for this is better design), some other errors, however, only need to be addressed near the top level of the code base. Exceptions have been invented just for that. Third, the pattern I started my question with is already prevalent, my suggestion merely offers a nicer syntax for writing the same thing. Discouraging something by making it deliberately ugly is not the way to go, IMHO.

> [@stevengj](#):
>
> TLDR: it was rejected in 2012 since `rethrow()` is semantically sufficient (this is just syntactic sugar), but in 2022 @StefanKarpinski is at least vaguely supportive. But someone needs to submit the PR, which would involve:
> 
> 1. Changing the parser to parse this syntax
> 2. Changing the lowering to lower this syntax to a sequence of `if … rethrow() …` statements.

Thanks for the heads up, at least now I know where to look for it.

---

<div class="post-metadata">

### Author: ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)
#### Post date: [July 21, 2023, 7:42am UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/17 "2023-07-21T07:42:14Z")

</div>

> [@mrufsvold](#):
>
> I even saw a discussion here not that long ago about the performance of checking `hasmethod` vs just running the function and catching the `MethodError` and the latter was better.

I believe `hasmethod` and others will become zero-cost in 1.10.

---

<div class="post-metadata">

### Author: ![aplavin](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/aplavin/32/222056_2.png) [@aplavin](https://discourse.julialang.org/u/aplavin)
#### Post date: [July 21, 2023, 7:43am UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/18 "2023-07-21T07:43:14Z")

</div>

Regarding the type-based catch approach, its details need to be carefully thought out in light of [GitHub - JuliaServices/ExceptionUnwrapping.jl: "I started by producing, and the rapping came second to that, because I wanted to fill out the beat." - Awkwafina](https://github.com/JuliaServices/ExceptionUnwrapping.jl) and concerns voiced there.

---

<div class="post-metadata">

### Author: ![mkitti](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mkitti/32/12459_2.png) [@mkitti](https://discourse.julialang.org/u/mkitti)
#### Post date: [July 21, 2023, 5:57pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/19 "2023-07-21T17:57:47Z")

</div>

Let’s figure out how to make this happen with a macro.

Here’s the closest valid syntax.

```julia
@errdispatch try
    # do something
catch e
    e::AssertionError -> println("AssertionError")
    e::InexactError -> println("InexactError")
end

```

To be continued…

---

<div class="post-metadata">

### Author: ![mrufsvold](https://sea2.discourse-cdn.com/julialang/user_avatar/discourse.julialang.org/mrufsvold/32/31600_2.png) [@mrufsvold](https://discourse.julialang.org/u/mrufsvold)
#### Post date: [July 21, 2023, 8:28pm UTC](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840/20 "2023-07-21T20:28:22Z")

</div>

Sorry for the tangential question, but how do you get a macro to keep capturing after a line break without a `begin`?

[Next page](https://discourse.julialang.org/t/new-syntax-suggestion-catch-with-type-specs/101840.md?page=2)
