-
Notifications
You must be signed in to change notification settings - Fork 17.7k
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: "onerr return" #32848
Comments
I like how readable the error handling becomes with this proposal, especially by re-using return. I think using “otherwise” instead of “or” might fit even better, albeit be a bit on the long side for a keyword. Is the idea to only allow return or other statements, too (calling another function, panic, ...)? It reminds me of Perl, is that where the idea came from? |
Hmm, I'd originally thought of it as Actually, I suppose technically it could be used as a general error handling keyword: err := DoSomething() or {
fmt.PrintF("We got error %n",err)
do other stuff...
} But I won't push that far in this proposal if there's resistance to it. It's enough to get rid of the |
I am not a fan of this syntax. The fact that |
|
We could also call it func (this *ReaderThing) readBytesFromFile(filename string, maxBytes int) (bytesRead int, err error) {
f, err := os.Open(filename) onerr return 0, err
...
} |
I like the idea a lot, but I don't think |
I understand the flow, it just doesn't look natural. Will the func (this *ReaderThing) readBytesFromFile(filename string, maxBytes int) (bytesRead int, err error) {
f, err := os.Open(filename) or doSomethingElse() && return 0, err
...
} Which imho adds cognitive load. |
No, this isn't supposed to allow chaining. It just means: func (this *ReaderThing) readBytesFromFile(filename string, maxBytes int) (bytesRead int, err error) {
f, err := os.Open(filename) [but if err != nil] [do this]
...
} In the strictest version of this proposal, it only accepts |
Very good proposal indeed, tackle exactly what we try to achieve - syntactic sugar for |
Well, this is much better than flawed stat := try(try(os.Open(fileName)).Stat()) File descriptor leak here — the example taken from comment in a popular widely supported issue where someone proposed to leave everything as is. There’s no RAII in Go to handle this. |
This comment has been minimized.
This comment has been minimized.
No-one (except maybe complete newbies) writes code like this. |
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This isn't an optimal example because the file descriptor actually will get cleaned up in the current implementation of Go with this indulgent finalizer: https://github.com/golang/go/blob/master/src/os/file_windows.go#L59 This undocumented behavior (which certainly shouldn't be part of any compatibility agreement) presents somewhat of a false sense of security to me (not sure about what other people think). However, it would be of benefit to think of other counter-examples for this reason. |
@as it can easily be some custom resource handler that has no finalizers |
would you like to talk english this way too ? "eat apple i like" |
I kind of like the way that this pushes error handling over to the right, where it is easier to skip when skimming the code. But I think we need more clarity on what can follow Also it's a bit odd to have to write the |
This does not seem true to me. With standard scoping rules the variables declared in an assignment are only visible after the assignment is complete. x := 1
{
x := x + 1
fmt.Println(x)
} This will print 2: the I think you are suggesting that the |
This proposal does not have strong supported based on votes for the initial comment. The scoping issue is not resolved. In a case like Based on these comments, this looks like a likely decline. Leaving open for a month for final comments. |
There were no further comments. |
Proposal: "onerr return"
Edit: Originally this was
or return
, but I likeonerr return
better since it's more explicit about what we're doing and why.Current syntax:
Proposed syntax:
Basically, if the last thing returned by a function is an error type,
onerr
checks if it's null, and if not, runs the statementreturn 0, err
.Specifically:
onerr
can only follow a function that returns typeerror
as its last return value.os.Open()
is stored tof, err
as normal.onerr
examines the last returned value of the function call (which must be typeerror
), and executes the subclause if it is not nil.return
statement executed with theonerr
clause follows standard scoping rules, which means thaterr
is visible to it (as aref
andfilename
andmaxBytes
).err
has already been assigned to by the time theonerr
clause executes, and is visible due to scoping rules, so it's perfectly valid to access. There's nothing new or magical here.Edit:
As an alternative (but only if we can be sure this won't break things or induce too much cognitive load) Allow block statements:
The text was updated successfully, but these errors were encountered: