Explicit is better than implicit, but there may be exceptions of the rule.
Before:
request, err := http.NewRequest(http.MethodGet, "http://example.com", nil)
if err != nil {
log.Println(err)
return
}
_ = request
After:
request, err := http.NewRequest(http.MethodGet, "http://example.com", nil) {
log.Println(err)
return
}
_ = request
Would you consider yourself a novice, intermediate, or experienced Go programmer?
Novice. 6 months using Go.
What other languages do you have experience with?
C/C++ and just a little bit of Java, C#, Python, JS, Elixir.
Would this change make Go easier or harder to learn, and why?
Insignificantly harder to learn: change introduces one simple thing to know.
Has this idea, or one like it, been proposed before?
Yes, there are 1 relative (#33113), 2 relatively similar (#33074, #33029), 2 very similar (#32848, #37243) proposals.
Who does this proposal help, and why?
This proposal helps every Go programmer and to every who switches to Go from another language. Why?
It will reduce "if err != nil" code line, improves readability and developer's productivity, because no one will see "if err != nil" after every function call, no one will wasting time typing this line. Code will become clearer.
For those switching from another language to Go, this will soften their attitude towards error handling in Go.
What is the proposed change?
Introducing new syntax construction when function call.
Is this change backward compatible?
Yes, absolutely.
Show example code before and after the change.
Shown at the beginning of the proposal.
What is the cost of this proposal? (Every language change has a cost).
The cost is time of implementing it.
Can you describe a possible implementation?
No.
How would the language spec change?
One paragraph describing this change will be added.
Orthogonality: how does this change interact or overlap with existing features?
The change does not conflicts or overlap existing features.
Is the goal of this change a performance improvement?
The goal is increasing performance of developer: in creating and reading code.
Does this affect error handling?
Yes.
If so, how does this differ from previous error handling proposals?
The reason, why #33074 and #33029 were declined is as said in https://github.com/golang/go/issues/33029#issuecomment-537238217 :
... it requires a new keyword, which while not impossible, is a higher bar for a language change. It also introduces yet another assignment form ...
The reason, why #32848 was declined due to a problems with scope and introducing one more keyword.
The reason, why #37243 was declined due to a problems with ?? operator that has another meaning is C#. (and in my opinion operator ?? just does not fit the Golang language)
Current proposal does not do this. There is no new keyword, no new assignment form and no new operator. Language stay as simple as before.
The only questions I have for now are:
In my opinion checking "if err != nil" is a clear and great error handling mechanism and it seems that nothing can really take place of it in Go. But it's a problematic to type this line literally after every function call, that return an error. Readability suffers too.
So let the compiler do the job for us. Reducing this line will have a big impact on code readability and programming experience.
But it's a problematic to type this line literally after every function call, that return an error.
What is the problem, can you please elaborate? Where you see redundancy or duplication, I see clarity.
Readability suffers too.
Can you substantiate this position? It feel like you don鈥檛 like to read the error checks so they hurt your readability. I do like to read the error checks for two reason:
What is the problem, can you please elaborate? Where you see redundancy or duplication, I see clarity.
The problem is that code gets bigger due to ubiquitous "if err != nil" line. It is clear and it's obvious, that after function call there might an error happen.
Now if you call a function it's necessary typing two lines:
Can you substantiate this position? It feel like you don鈥檛 like to read the error checks so they hurt your readability.
This proposal does not aims to get rid of the error checks. The only thing wanted is letting compiler "type" != nil condition for us.
I do like to read the error checks for two reason:
1.They prove to me that the author of the code has thought about how the error from the call should be handled.
2.They highlight the most important part of the authors error handling, the bit that happens after the != nil {, and the return statement.
Again, this suggestion does not mean that you do not should to read error checks. Check out the proposal again, please.
There is no new keyword, no new assignment form and no new operator. Language stay as simple as before.
I'm sorry, but I disagree - you are changing the language in a very direct way. You can't claim that the language stays as simple as before when you're adding a new form of "if" conditionals.
You are right. It's wrong to say that language will as simple as before. But before to check errors it was needed to know:
After this change it will be needed additionally to understand how this "new 'if' form after function call" works. One more thing to know. The helpful syntactic sugar if you let.
See also #40432.
The description suggests that I can put a block after any function that returns at least one result.
Is this OK?
func F(err error) {}
func G() error { return nil }
func H() {
F(G() { log.Fatal("G failed") })
}
@AlisherFozilov are you aware that the following is already possible in Go?
if request, err := http.NewRequest(http.MethodGet, "http://example.com", nil); err != nil {
log.Println(err)
return
}
_ = request
EDIT: oh wait no. request is undefined after the if block. Damn this always gets me.
@AlisherFozilov Does this still work for discarded error values?
request, _ := http.NewRequest(http.MethodGet, "http://example.com", nil) {
return
}
_ = request
Based on the discussion above, and the emoji voting, this is a likely decline. Leaving open for four weeks for final comments.
Instead of...
request, err := http.NewRequest(http.MethodGet, "http://example.com", nil) {
log.Println(err)
return
}
...which is minuscule advantage over...
if request, err := http.NewRequest(http.MethodGet, "http://example.com", nil); err != nil {
log.Println(err)
return
}
Why don't we add if-like that check if it's nil or not, then execute something if not nil, like this:
request, err := http.NewRequest(http.MethodGet, "http://example.com", nil)
catch err {
log.Println(err)
return
}
No change in consensus.
Most helpful comment
I'm sorry, but I disagree - you are changing the language in a very direct way. You can't claim that the language stays as simple as before when you're adding a new form of "if" conditionals.