go: proposal: Go 2: simplify error handling with ? and ...
The try proposal #32437 was recently declined. This is an alternate proposal to achieve the goal of simplifying error handling. It has two parts:
- Make
EXPRESSION?return a bool, true if the expression is a non-blank value, false is the expression equals the blank value. So, for interface types, it would be equivalent toEXPRESSION != nil.
Usage:
func CopyFile(src, dst string) error {
r, err := os.Open(src)
if err? {
return fmt.Errorf("copy %s %s: %v", src, dst, err)
}
defer r.Close()
w, err := os.Create(dst)
if err? {
return fmt.Errorf("copy %s %s: %v", src, dst, err)
}
if _, err := io.Copy(w, r); err? {
w.Close()
os.Remove(dst)
return fmt.Errorf("copy %s %s: %v", src, dst, err)
}
if err := w.Close(); err? {
os.Remove(dst)
return fmt.Errorf("copy %s %s: %v", src, dst, err)
}
}
- Make
return ..., EXPRESSIONfill in as many blank values as needed to fulfill the signature of the function.
Usage:
return ..., err
return ..., fmt.Errorf("something went wrong: %v")
Rationale:
Given the design goals for improving error handling, it is difficult to imagine any proposal that doesn’t end up being non-orthogonal with if and defer. This makes it simpler for text editors to insert the correct boilerplate for an early return automatically, and it saves a few characters for programmers who type the whole thing out manually.
About this issue
- Original URL
- State: closed
- Created 5 years ago
- Reactions: 36
- Comments: 20 (11 by maintainers)
I was going to open an issue to propose the same thing as the 2nd point.
I see two main benefits of this:
This proposal solves both issues beautifully.
Compare
Let’s throw the “ellipsis” keyword here so that this issue can be found more easily, because I think that’s what “…” is commonly called.
Also, if #21291 passes, this could be used to return explicitly “all-zeros” with
return ...IMO those are 2 different proposals, for example I really like the
..., errpart but absolutely hate the first.@carlmjohnson I love the
return ..., errit might be worth making a separate proposal just for it.Isn’t named return values an alternate solution for ellipsis?
We don’t have to explicitly return the zero values each time this way. They are auto populated at function start. If the naked return affects the readability, we can even use
The
?part of this proposal looks essentially the same as #32845.The
ifstatement is likeLooks like
err?returns a bool. I think using?to replace!=nildoesn’t solve the error handling problem at all.io.Reader/Writer is the exception that proves the rule. Almost nothing else can return both an error and a result. It’s pretty much one or other. IO is different because it is possible to do a partial read/write and still get meaningful results, but there’s no such thing as half an HTTP response header or half a decompressed file.
Yes, I have come to the conclusion that apart from
try(), saving a few characters is all that is possible, because all the other proposals end up reinventingifanddeferwith non-orthogonally different semantics.Hey, thanks for the proposal. But I’m having issues with understanding what value it brings. Both options, conceptually do not bring any solutions to the problem. They just save few characters that you have to type. It feels more like a workaround than a solid solution.
Didn’t see that issue. I’ve seen proposals to allow
return _, err(although I can’t find an issue ATM), but notreturn .... The difference betweenreturn _andreturn ...is that...would return as many values as necessary, not just one, so it could be used in any function with an error return.Second point looks good