-
Notifications
You must be signed in to change notification settings - Fork 17.9k
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: spec: conditional return with "return if" #70147
Comments
Please fill out https://github.com/golang/proposal/blob/master/go2-language-changes.md when proposing language changes |
I'm not sure how you'd have only "a few general Errorhandlers" when the return types need to match. Generics aren't that useful since we don't infer based on return types. |
Let's take for example a handler. I would be using gin to make things simpler for the example. func (h *H) someHandler(c *gin.Context) {
var req someType
err := c.ShouldBindJSON(&req)
return if HandleErrorBadJSON(err) // the function will handle the error and return the request
// we can go to one line also, but this is not the goal
err:= doValidations(req)
return if HandleBadRequest(err) // we can have more function params if we like
resp,err;=h.CallControllerFunction(req)
HTTPResponse(resp,err,c)
// this last one does not even need a return statement
} PS. I understand that Go is not very keen in hiding details or making something one line for the shake of being shorter. Its like a nested for loop. Sometimes you want to break from inside the loop. |
I agree with @seankhliao that it seems like this would essentially require each function to have at least one error handling function of its own, since the error handling function is overloaded with two responsibilities: it must both decide whether to return and provide the values to return. I expect that in practice most authors would use this feature with inline closures instead, if I'm correct in assuming that the error handlers will typically be tightly coupled to a single function that calls them. For example: func SomeFuncName(x, y, x any) (int, any, error) {
errorHandler := func (err error) (bool, int, any, error) {
if err != nil {
return true, 0, "something", err
}
return false, 0, nil, nil
}
a, err := someCall(x, y, z)
return if errorHandler(err)
} Some additional examples that are more like real code that you might write using this pattern could help counter my assumption that error handlers would be tightly-coupled to their callers. It's possible that the contrived example you chose made this seem less flexible just because of the rather unusual combination of return types you chose. 🤔 Subjectively, I find it awkward that the error handler function is required to return values for all of the caller's return values even when the first return value is I understand that this is somewhat consistent with how it's typical (though not universal) for a function to return zero-values for everything except its Comparing this to the (already-declined) #53017, I find the older proposal's "Iteration 2" very similar but with a more concise syntax that I generally prefer. I believe the above example would've been written as follows under that proposal: func SomeFuncName(x, y, x any) (int, any, error) {
a, err := someCall(x, y, z)
return 0, "something", err if err != nil
} The author of that proposal rejected that form in favor of the final "Iteration 3", which I think would appear like this: func SomeFuncName(x, y, x any) (int, any, error) {
a, err := someCall(x, y, z)
return if err != nil { 0, "something", err }
} This variation was declined on the grounds that it's only marginally different than the current idiom: func SomeFuncName(x, y, x any) (int, any, error) {
a, err := someCall(x, y, z)
if err != nil {
return 0, "something", err
}
} All of these have the distinct advantage of keeping the expressions defining what to return on error close to the I agree with the reasons given for declining the other proposal, but I'm afraid I find this new proposal less readable than either of the previous proposal's ideas due to moving the expressions that decide the return value of one function into another function potentially quite far away from the one I'm currently trying to read. Therefore I'm afraid I'm voting 👎 on this one. 😖 |
As noted above, there is some overlap with previous issues. The phrase The emoji voting is not in favor. For these reasons, this is a likely decline. Leaving open for four weeks for final comments. |
No further comments. |
Introduction
Proposal Details
First of all, I would like to note that I was very reluctant to make this step, but I really think it is simple and will simplify code a lot.
Goal: Simplify repetitive if blocks that return.
Example: Error handling.
We can generalize the inner block of the if function, but we still have to process the result with an if statement to exist the outer function. To many lines of code for something that could be a one-liner.
How it will work
The requirements would be
This will greatly reduce the number of lines we write in an application. Especially in error handling.
We will write a few general Errorhandlers and then simply use
return if ErrorHandler(err)
If we want to change our handling, we would have to change just a few functions.
Of course, this is not only helpful in error handling. It will also help reduce the cognitive workload of functions with multiple if/else or switch statements.
Keyword to use
If there is no language ambiguity in using return if, then it's the most natural choice.
We can also use return on or concatenate and use a single word.
The text was updated successfully, but these errors were encountered: