Skip to content
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: skipped return values #64859

Closed
vispariana opened this issue Dec 24, 2023 · 3 comments
Closed

proposal: skipped return values #64859

vispariana opened this issue Dec 24, 2023 · 3 comments

Comments

@vispariana
Copy link

Proposal Details

Proposal

Adding a new underscore syntax to return statements, which returns the zero value for the corresponding type.

val, err := f()
if err != nil {
    return _, err
}
return val, _ 

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 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.

@gopherbot gopherbot added this to the Proposal milestone Dec 24, 2023
@seankhliao
Copy link
Member

Duplicate of #21422

@seankhliao seankhliao marked this as a duplicate of #21422 Dec 24, 2023
@seankhliao seankhliao closed this as not planned Won't fix, can't repro, duplicate, stale Dec 24, 2023
@seankhliao
Copy link
Member

see also #19642, #21182, #61372

@vispariana
Copy link
Author

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?

@golang golang locked and limited conversation to collaborators Dec 23, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

3 participants