-
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: Go 2: add "or err: statement" after function calls for error handling #33029
Comments
I don't think the syntax fits well with the rest of the language. Currently an identifier followed by a colon is always a label or a case statement; here it is a variable declaration. Currently any conditionally executed statement is always in a block delimited by curly braces; here it is standalone. |
I put : since to me, it visually seems to fit well. One solution would be to do what the handle part of the previous draft did:
I would have preferred if the braces were not mandatory, but I understand the sentiment. |
Has some clear similarities to #32848, although it's not identical. |
Indeed. While very similar, I'd prefer to keep the try/catch behavior of shifting the last value. And I really do think this construct has potential usability for not just error types. |
While this idea is interesting, it doesn't reduce boilerplate that much, compared to: func CopyFile(src, dst string) error {
if r, err := os.Open(src); err ! = nil {
return err
}
defer r.Close()
} |
True, but if you look closely, your code will not compile. It is also a bit harder to read, due to the initial if which will always force you to read the whole line to see if there is an initial statement hidden in there. And it's also why I prefer it a block is not mandated on the right side |
You're right, I made a mistake, it needs to be like this: func CopyFile(src, dst string) error {
if r, err := os.Open(src); err != nil {
return err
} else {
defer r.Close()
}
return nil
} Admitted, an if with an initializer is a bit harder to read, and harder to write, but I don't think this proposal is such a significant improvement to warrant new syntax. |
I have a very similar proposal #33161 so I probably should have just collaborated with you in it. My main concern with this proposal is that there isn't a visual cue at the beginning of the line that the function usually returns an error as its final parameter. Questions:
Could I use this with an
Could it be used inline?
|
Altering the defer and go statements could be useful, though it might make the implementation more difficult. I do however prefer if this suffix works on any type, as stated in the addendum. On the other hand, it's probably better if inlining isn't allowed. Your examples seems to reduce readability. |
The |
This proposal introduces a new keyword I think the (modified) syntax is something like
The Can this construct be used outside of an assignment statement? It would be awkward to have a block embedded in a larger expression. But only permitting this in an assignment statement does not seem very orthogonal. This is a little bit shorter than writing the standard This idea mixes together an assignment statement, an if statement, an implicit conditional test, and a variable declaration. In general, in Go, individual concepts are isolated and can be used independently. This is an odd hybrid of several different ideas. |
I think that, in order to for this to be useful, it has to cover Return, Expression, Assignment and ShortValDecl statements. Which would, unfortunately, make the spec quite a bit more complex. That might be aleviated if the In terms of length, I would still prefer that besides a Block, a simple statement should also be allowed for simple handlers. |
As noted above, this is an hybrid of different ideas. And it requires a new keyword, which while not impossible, is a higher bar for a language change. It also introduces yet another assignment form. Therefore, this is a likely decline. Leaving open for four weeks for final comments. -- for @golang/proposal-review |
There were no further comments. |
I'd like to draft the following proposal for an expression used for error handling. I believe it achieved the following goals :
For disclosure, while I do think the try proposal needs improvement, it is on the right track as it covers the first two of the aforementioned points. I also don't think this will get any traction, though I do hope for some discussion, to at least know it was considered.
Design
The draft introduces a new syntactic form: an optional
or <identifier>: <Statement>
expression added to the Return, Expression, Assignment and ShortValDecl statements.Edit: after the first feedback, perhaps the grammar should be changed to
or <identifier> <block>
to better align with current syntax constructs.This expression works similarly to
try
orcheck
. If the preceding expression list produces one or more values, the last value is checked whether it is different than its zero value. If it is not, any previous values except it will be returned or assigned. If the last value is nonzero, it will be assigned to the identifier to be used in the scope of the following statement.The now well known function can be rewritten as:
Edit:
Since the trailing part is a statement in itself, it can be used to decorate errors, handle them (in a code block if needed), breaking and continuing from loops, etc. It also doesn't allow nesting of invocations, which would otherwise reduce readability IMHO.
Drawbacks
One obvious drawback is that it will be more difficult to implement and handle by various tools that a function.
It also may or may not be backwards compatible. Current keywords cannot be used as identifiers,
however this implementation could avoid defining
or
as another keyword. I do not have enough knowledge to know this if feasible.Addendum
While everything is up for debate, I haven't so far restricted the last value to only be of the error type. This construct seems handy when obtaining a value from a map as well - either obtaining it or dealing with its absence.
Edit:
Example:
The text was updated successfully, but these errors were encountered: