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: Leaf Operator with "throw" keyword for error handling #51415
Comments
|
Thanks for reviewing, I will update the proposal, here is a summary before to update it.
|
In general we don't want breaking changes in Go. See https://go.googlesource.com/proposal/+/refs/heads/master/design/28221-go2-transitions.md . |
Neither of the goroutine examples (before and after) seems to show proper error handling. With regards to returning an error upwards the chain, I recommend including wrapping of the error in all of the location. It's relatively common to add information to the errors. |
The error info already comes from the source of error add other description on top of other error reflects the absence of something like stacktrace (without using panic) when errors is well designed is not need it to wrap errors every time, one error description is enough. Any way on the go routine example I just returning the error but you could call a function as well that is part of the definition so you could call fmt.Errorf to add more information |
Doesn't seems we have a lot of flexibility to add features on language level, could be useful design a new layer for compiler? |
The "Before" goroutine example does not compile https://gotipplay.golang.org/p/yD_rihzRN0e. Similarly the "after" approach is not clear where the when the error will be synchronized.
That is not my experience. Stack traces don't cross goroutine boundaries, which means there's a need to augment the information. Similarly, there is information that is not captured in stacktraces. If a language feature makes it more difficult to include extra information when calling back it creates an incentive to not use them, which can make software harder to debug. Or in other words, it would be better to include the error wrapping in the examples. |
Thanks for your response I understand you point of view sorry I was wrote examples directly on the issue without check if compiled |
I've close because after some feedback I think this need to be more elaborated, please feel free to propose something like that if someone has better English writing ✍️ Could be nice the discussion for a new layer that accepts plugins what do you think 🤔? Thanks a lot to all reviewers! |
Author background
Would you consider yourself a novice, intermediate, or experienced Go programmer?
Novice programmer on Go
What other languages do you have experience with?
Java, Javascript, Python, PL/SQL, Pascal
Related proposals
Has this idea, or one like it, been proposed before?
No
If so, how does this proposal differ?
N/A
Does this affect error handling?
Yes
If so, how does this differ from previous error handling proposals?
This proposal adds the leaf concept as new operator and add a new reserved keyword for error handling. On the future this concept could be used for new behaviours to do other things like validations for example.
Other proposals
Based on the different proposals, I don't see enought flexibility to add custom function return types, and creating new code blocks like try, catch, etc. keeps limited the possibility to handle different nested errors because you need to catch everything and the catch concept is a design problem right now in Java and other languages as well.
Also combinations of different symbols ! # ^ sounds good and others looks complex (skipping the cryptic part) but is not easy to define a custom return type the same happens with must, guard etc.
Here are the meta document with all proposals language: Go 2: error handling meta issue #40432
Is this about generics?
No
If so, how does this relate to the accepted design and other generics proposals?
N/A
Proposal
What is the proposed change?
Add new unary operator as leaf concept and add a new reserved keyword to propagate errors.
Who does this proposal help, and why?
Helps to developers avoid writing repeated code when propagating errors, also opens the door to add new functionalities on the future based on leaf paths.
Please describe as precisely as possible the change to the language.
Add
->
as new unary operator, andthrow
as reserved keyword.Skeleton should be something like:
fn() -> [reserved keyword] [func|any]
The operator must have these constraints:
The reserved keyword must have these constraints:
What would change in the language spec?
Add new section as
Leaf Path
https://go.dev/ref/spec#Declarations_and_scopeAdd new keyword
throw
https://go.dev/ref/spec#KeywordsAdd new operator
->
https://go.dev/ref/spec#Operators_and_punctuationAdd new section as
Leaf Operator
https://go.dev/ref/spec#OperatorsAdd example how to return an error https://go.dev/ref/spec#Errors
Please also describe the change informally, as in a class teaching Go.
This graph represents the flow of the next example, it is independent of how is handled the error, and I think the proposal solution should be in this line to avoid flow modifications or new code blocks, and must be interpreted by the compiler.
The solution should be take into account the returning type of the function, I think that is the most conditional thing to choose a specific solution.
This proposal follows the current Golang paradigm avoiding cryptic implementations and using an existent operator like we are using for channels <- but inverted as representing a leaf path (that opens the possibility to add more functionality on the future) and using a new "throw" keyword as indicator that the error will be returned.
To be consistent I respect all values returned on the function return, but this could improve using only the error.
The idea is something like is doing on Haskell here is an example https://www.haskellforall.com/2021/05/the-trick-to-avoid-deeply-nested-error.html
See examples below.
Is this change backward compatible?
Yes, this change is backward compatible
Show example code before and after the change.
Orthogonality: how does this change interact or overlap with existing features?
The new operator
->
is a leaf concept, defines a flow to do after a function execution, if this operator is found after a function invocation the error will be returned by the leaf body when the throw keyword is present, so this interacts directly after a function invocation.Is the goal of this change a performance improvement?
No
N/A
N/A
Costs
Would this change make Go easier or harder to learn, and why?
Makes Go easier to learn because is a proposal that avoids code repetition and adds a new concept that could be powerful on the future to have more flexibility in one line.
What is the cost of this proposal? (Every language change has a cost).
Modify the compiler, linter tools to interpret the new operator and the new reserved keyword, update docs as well.
How many tools (such as vet, gopls, gofmt, goimports, etc.) would be affected?
I think vet, gopls, gofmt and maybe I missing some one.
What is the compile time cost?
Should be despreciable at relative terms, but this is subjective right now
What is the run time cost?
Not affected
Can you describe a possible implementation?
I will need help on this
Do you have a prototype? (This is not required.)
No right now
The text was updated successfully, but these errors were encountered: