You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
In an idiomatic codebase, we often come across functions having multiple return values, with the last of them being an error type. Handling errors in these functions usually makes us write codes like: return 0, err return "", err return nil, err return somepkg.SomeStruct{}, err
These lines are found in error-checking conditions, so when writing them the other value being returned beside the error value is not of concern to the developer. What they actually mean is: "ignore the first value and propagate the error, or a wrapped/modified version of it". But the language does not allow the dev to do what they intend, and instead, they have to look up the function's signature to fill up the correct zero values - some unnecessary characters that are only demanded by the compiler, and clutter developer's view. This is much worse when the function returns structs with long names.
Adding the _ syntax to return statements enables developers to better - and easier - express their intentions. No more needing to check the signature to write weird statements like return "", false, err, and makes the code cleaner and more expressive to the reader. The change is very small, backward-compatible and Golang developers are already used to the underscore syntax with the same meaning in other contexts.
Possible arguments
Use pointers for structs with long names, so you can just return nil
This is not a solution as it has consequences on performance. Why offer a tradeoff between more cluttered code and busier GC, when we can have none? And still doesn't solve the problem with primitives.
Use naked returns
Naked returns are only suggested for very short functions and their main use is with deferred functions and documenting return values. Excessive use of naked returns is VERY error-prone, and a nightmare to read.
Define a variable in the outer scope
This helps with the issue to some extent, but there are several downsides. Does not work for primitive types, and for structs you have to choose a short name for the variable, or else you end up at square one. And reducing variable scopes to the smallest necessary scope is a best practice, helps you avoid problems with variable shadowing.
What if some people want to return a usable value AND a non-nil error? Why add a syntax that will only be of use to some people?
They are a minority. Though it's indeed possible to do so - just like it's possible to put errors first in return values, but nobody does that - it's widely accepted that when an error is present, all the other return values should be considered invalid and should be ignored. I can confidently say this addition will be useful to the vast majority of Golang developers.
The text was updated successfully, but these errors were encountered:
Thank you for the directions. However they were multiple slightly different proposals and some required significant changes to the language. What I propose is not introducing a universal zero identifier. Underscores are only allowed in assignments and return statements. No ambiguous or confusing syntax is introduced.
Ian had a comment:
Another comment. If we use _, then we can see code like
_ = x
return _
That seems potentially confusing.
Here what the developer is trying to achieve is more confusing than the code itself. Why would someone want to skip the only (or all) return values of a function? it has no meaning, and compiler can even prevent that as it's most likely a bug.
Other than that, I saw no strong arguments against the proposal. The only one being Rob Pike's "not now" comment back in 2012. Maybe it's time to bring this up again?
Proposal Details
Proposal
Adding a new underscore syntax to return statements, which returns the zero value for the corresponding type.
Rationale
In an idiomatic codebase, we often come across functions having multiple return values, with the last of them being an
error
type. Handling errors in these functions usually makes us write codes like:return 0, err
return "", err
return nil, err
return somepkg.SomeStruct{}, err
These lines are found in error-checking conditions, so when writing them the other value being returned beside the error value is not of concern to the developer. What they actually mean is: "ignore the first value and propagate the error, or a wrapped/modified version of it". But the language does not allow the dev to do what they intend, and instead, they have to look up the function's signature to fill up the correct zero values - some unnecessary characters that are only demanded by the compiler, and clutter developer's view. This is much worse when the function returns structs with long names.
Adding the
_
syntax to return statements enables developers to better - and easier - express their intentions. No more needing to check the signature to write weird statements likereturn "", false, err
, and makes the code cleaner and more expressive to the reader. The change is very small, backward-compatible and Golang developers are already used to the underscore syntax with the same meaning in other contexts.Possible arguments
This is not a solution as it has consequences on performance. Why offer a tradeoff between more cluttered code and busier GC, when we can have none? And still doesn't solve the problem with primitives.
Naked returns are only suggested for very short functions and their main use is with deferred functions and documenting return values. Excessive use of naked returns is VERY error-prone, and a nightmare to read.
This helps with the issue to some extent, but there are several downsides. Does not work for primitive types, and for structs you have to choose a short name for the variable, or else you end up at square one. And reducing variable scopes to the smallest necessary scope is a best practice, helps you avoid problems with variable shadowing.
They are a minority. Though it's indeed possible to do so - just like it's possible to put errors first in return values, but nobody does that - it's widely accepted that when an error is present, all the other return values should be considered invalid and should be ignored. I can confidently say this addition will be useful to the vast majority of Golang developers.
The text was updated successfully, but these errors were encountered: