-
-
Notifications
You must be signed in to change notification settings - Fork 5.5k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
add try/catch/else #42211
add try/catch/else #42211
Conversation
Maybe something like |
|
I didn't really look into what Python does when I wrote it (not sure if there are any other languages as well with this construct), but that might give some useful precedent here. They also called it |
I guess when I see E.g. in But in I guess I'm very used to thinking of So I would prefer something like |
EDIT: scrap this suggestion.
|
I still like
This seems too close to try
...
catch
...
if ...
...
end
end which has a completely different meaning. It also very likely leads to parsing ambiguities or would at least significantly complicate the rules for parsing |
Oh, good point. Let's scrap the |
I would also suggest that we disallow |
If we disallow |
There's a similar concept in But FWIW I think |
I think |
That's definitely an interesting idea. We might want it to work just like function dispatch though, which would again be asymmetric to how |
I also like |
Yaeh, I think focusing on BTW, it looks like try-catch-else was discussed before: #21130. According to @StefanKarpinski
|
What about?
Its not a breaking change since |
It seems like the minimally controversial option is to allow what Python allows: |
It has the same issues I pointed out in #42211 (comment).
Should we care about the order as well? Python also disallows |
I would find it easiest to read if we:
|
Do you mean |
Ooof. Yes I definitely meant |
The argument for requiring |
Triage says 👍 and we like requiring |
This PR allows the use of `else` inside try-blocks, which is only taken if no exception was caught inside `try`. It is still combinable with `finally` as well. If an error is thrown inside the `else` block, the current semantics are that the error does not get caught and is thrown like normal, but the `finally` block is still run afterwards. This seemed like the most sensible option to me. I am not very confident about the implementation of linearization for `trycatchelse` here, so I would appreciate it if @JeffBezanson could give this a thorough review, so that I don't miss any edge cases. I thought we had an issue for this already, but I couldn't find anything. `else` might also not be the best keyword here, so maybe we can come up with something clearer. But it of course has the advantage that it is already a Julia keyword, so we don't need to add a new one.
0f651d7
to
2bbf924
Compare
Co-authored-by: Jeff Bezanson <jeff.bezanson@gmail.com>
Needs docs, or are they elsewhere already? |
This PR allows the use of `else` inside try-blocks, which is only taken if no exception was caught inside `try`. It is still combinable with `finally` as well. If an error is thrown inside the `else` block, the current semantics are that the error does not get caught and is thrown like normal, but the `finally` block is still run afterwards. This seemed like the most sensible option to me. I am not very confident about the implementation of linearization for `trycatchelse` here, so I would appreciate it if @JeffBezanson could give this a thorough review, so that I don't miss any edge cases. I thought we had an issue for this already, but I couldn't find anything. `else` might also not be the best keyword here, so maybe we can come up with something clearer. But it of course has the advantage that it is already a Julia keyword, so we don't need to add a new one. Co-authored-by: Jeff Bezanson <jeff.bezanson@gmail.com>
I just noticed this change in the release notes of v1.8. Since it is not stable yet I hope its OK if I propose a different syntax. I really think the control flow and the scopes will be unintuitive with the usage of For example, when you have some code that should only run when the try is successful, a simple solution is to write it like: try
x = can_go_wrong()
use(x) # while this actually should never go wrong
catch e
handle_error(e) # (x is not defined here)
end Writing this the new way, the new block should have the same scope as I propose to use the word try
x = can_go_wrong()
then
use(x) # same scope as try
catch e
handle_error(e) # (x is not defined here)
end as opposed to try
x = can_go_wrong()
catch e
handle_error(e) # (x is not defined here)
else
use(x) # same scope as try
end And I argue that it is easier to read:
instead of having to jump when reading:
It also reads natural to use try
x = can_go_wrong()
then
use(x)
end Note that the new block (also when using How Python did it is I think an example of confusing semantics: try:
raise ZeroDivisionError()
except ValueError as e:
print("This block is not run because it does not match the exception")
else:
print("This is also not run because try did not succeed") You could say that this is less of a problem in Julia since there is always just one 'catch-all' block, so if that block did not run it always means that the try did succeed. But it will get the same ugliness if multiple typed catch blocks will ever be added (as discussed in #7026). |
I believe this is largely subjective and I don't feel like one is significantly more intuitive than the other. I think not having to introduce a new keyword and not breaking with Python are more objective arguments for the current syntax. |
This PR allows the use of `else` inside try-blocks, which is only taken if no exception was caught inside `try`. It is still combinable with `finally` as well. If an error is thrown inside the `else` block, the current semantics are that the error does not get caught and is thrown like normal, but the `finally` block is still run afterwards. This seemed like the most sensible option to me. I am not very confident about the implementation of linearization for `trycatchelse` here, so I would appreciate it if @JeffBezanson could give this a thorough review, so that I don't miss any edge cases. I thought we had an issue for this already, but I couldn't find anything. `else` might also not be the best keyword here, so maybe we can come up with something clearer. But it of course has the advantage that it is already a Julia keyword, so we don't need to add a new one. Co-authored-by: Jeff Bezanson <jeff.bezanson@gmail.com>
This PR allows the use of
else
inside try-blocks, which is only takenif no exception was caught inside
try
. It is still combinable withfinally
as well.If an error is thrown inside the
else
block, the current semantics arethat the error does not get caught and is thrown like normal, but the
finally
block is still run afterwards. This seemed like the mostsensible option to me.
I am not very confident about the implementation of linearization for
trycatchelse
here, so I would appreciate it if @JeffBezanson couldgive this a thorough review, so that I don't miss any edge cases.
I thought we had an issue for this already, but I couldn't findanything.
else
might also not be the best keyword here, so maybe wecan come up with something clearer. But it of course has the advantage
that it is already a Julia keyword, so we don't need to add a new one.
Closes #21130