-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
proposal: Go 2: use keywords throw, catch, and guard to handle errors #40583
Comments
In the strongest possible terms, no. |
See #40432. Especially: https://go.googlesource.com/proposal/+/master/design/go2draft-error-handling-overview.md |
Just to play around with this a little, how do How can callers know that a function can throw (the "implicit checking/results" problem)? Pushing that into tooling doesn't seem to really solve the problem, because it requires people to set up and use the tool globally and consistently. |
For language change proposals, please fill out the template at https://go.googlesource.com/proposal/+/refs/heads/master/go2-language-changes.md . When you are done, please reply to the issue with Thanks! |
@gopherbot please remove label WaitingForInfo. |
It doesn't affect how defer works. It's standalone, similar to the "check/handle proposal".
For example fmt.Fprintln(os.Stdout, "") If you don't use tools like Why can't we use a similar tool to indicate if a function will throw? In IDE it might look like this: Just for the demo, we could use a better sign or color other than It's very easy to recursively analyze the code to know if a |
Throws semantics need to be explicitly defined as its introduces new control flow.
This is not possible statically when reflect Call, function variables and plugins are involved without explicit anotation. Errors are different in that the function signature shows explicitly whether an error is returned or not. |
I think it's the same as Go1's error. If you return an error as an interface, it will be hard to tell when a function will return an error or not.
Good point, I will take some time to add some examples for them. |
True but there was no claim here that its possible to know where all error values are originating from either. Errors dominately are returned as error types directly which is possible to analyse statically and not as |
At least we should avoid talking about "plugin" which is even unusable on Windows: #19282 (this 2017 issue is still open) For reflect, even you try to use reflect to hide throw, you will end up calling something like relfect.Throw which can still be statically analyzed. |
reflect can call normal go methods by name just fine. There is not constraint in the proposal or language that enforces functions called with reflect to need to use reflect.Throw. Its similar how fmt can not statically know if a Stringer implementing type that is passed in has the potential to panic or not. It needs to assume any function can panic.
At any rate. These question all reflect that implicit error checking/flow has issues and I dont think they can be satisfactory solved trying to mitigate them with expensive static analysis. |
The analyzer can tell you are passing function |
The analyzer can not know that in all cases if e.g. foo being an interface{} value (containing a type implementing Formatter or Stringer or something else) that came from somewhere populated at run time. The analyzer can be defensive and if can not be proven otherwise always assume there can be a throw but then there will be lots of places annotated with can throw which can lead to alot of boilerplate catching. I dont think the analyzer will be fast (requires whole program analysis) nor easy and it requires to use an IDE to better understand where errors/exceptions can come from. Happy to be proven otherwise. |
If we use
Such as python or javascript, they don't use catch everywhere. As long as you catch at their parent node, the analyzer shouldn't complain.
I think the complexity is O(n). As long as it's not O(n^2) I think we shouldn't define it's slow. We have a good language server which can cache the result. One node's change won't affect the whole tree, it will only affect functions depend on it. |
Have you seen https://golang.org/doc/faq#exceptions ? That said: I don't understand the difference between I don't understand the difference between I don't understand the difference between func Guard(f func()) (err error) {
defer func() {
if r := recover(); r != nil {
err = r.(error)
}
}()
f()
} |
Yes, I use Go for many years now, I think I know most of the debates and how hard it will be to challenge such a topic.
There are a lot. For example, panic will crash the application, throw won't. It's the same as when you forget to handle the err returned from a function, nothing will happen. We can discuss how to handle uncaught errors. Such as nodejs' uncaught exception.
My example above already showed, in
|
Thanks. I think you need to write down the precise semantics of these new constructs, because I do not understand them. All I've seen so far is examples and implementation. My apologies if I've missed a description. |
@ianlancetaylor Thank you for your feedback. After collecting more feedbacks I will try to add precise semantics, I may also modify the specs while reviewing them. I searched things like "golang where to share language draft design" with no luck. So I shared it here, hope to find people who have the willingness to work on this idea together. |
@ysmood this may be useful for your proposal. https://github.com/golang/proposal#proposing-changes-to-go |
|
Sorry, what you do mean? Can you give more details about your concern? |
i had misread part of the proposal, my bad. i was confused for a reason, haha |
Based on the discussion above and the emoji voting, this is a likely decline. Leaving open for four weeks for final comments. |
No further discussion. |
The proposal borrowed some ideas from The check/handle proposal.
One of the issues of "check/handle proposal" is that it doesn't support function chaining well: https://gist.github.com/DeedleFake/5e8e9e39203dff4839793981f79123aa.
To make a long story short, let's see some code examples first.
Without the proposal:
With the proposal:
Use keyword
guard
to convert the throw version to normal error value style, so that we can precisely handle each error separately:Currently, I created a demo lib to simulate the taste: https://github.com/ysmood/tcg/blob/master/example_test.go
We shouldn't just use the
panic
to do it. For the implementation ofthrow
, it's similar to setjmp and longjmp. I feel the performance won't be affected.To avoid forgetting
catch
we can statically do something similar to https://github.com/kisielk/errcheck by analyzingthrow
keyword.Sure the keywords are not decided, we can use other words if they are better.
Would you consider yourself a novice, intermediate, or experienced Go programmer?
Experienced
What other languages do you have experience with?
js, ruby, elixir, scala,c, c#, python, haskell, php, lua
Would this change make Go easier or harder to learn, and why?
Harder
Has this idea, or one like it, been proposed before?
Have researched the #40432, not able to find similar ones.
Who does this proposal help, and why?
Everyone, because error handling is used in most of projects.
What is the proposed change?
See the front description.
Is this change backward compatible?
No, it will add new keywords.
What is the cost of this proposal? (Every language change has a cost).
Users have to spend more time to master the error handling.
How many tools (such as vet, gopls, gofmt, goimports, etc.) would be affected?
All of them.
What is the compile time cost?
Minor cost.
What is the run time cost?
Minor cost.
Can you describe a possible implementation?
Only if we agree with this idea.
Do you have a prototype? (This is not required.)
No
How would the language spec change?
See the front description.
Orthogonality: how does this change interact or overlap with existing features?
Might overlap the panic.
Is the goal of this change a performance improvement?
No.
Does this affect error handling?
Yes.
If so, how does this differ from previous error handling proposals?
See the front description.
Is this about generics?
No.
The text was updated successfully, but these errors were encountered: