-
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: accept multiple return values as the last arguments to function calls #40387
Comments
Go 2 labels are not about language backwards compatibility. Any language change is marked as Go 2. |
There was some earlier discussion about this and why it has some complexity years ago in: #973 (comment) |
@martisch Thanks. I think the logic is pretty clear, just spread the input if it's a tuple and check if the type matches, if not compile error. |
If more people think it will make it harder to read the code, I'm ok to close it. But I don't think it will introduce a lot of unexpected behavior since everything is statically typed. |
see #32941 on tuples |
I think it's clear why |
@ianlancetaylor It's hard to define what is special and what is hard. It depends on perspective, for example, Go support variadic arguments only for last arguments, in that sense allowing func bar(a int, list ...int) {}
func main() {
list := []int{1,2}
bar(0, list...)
} So for me, it feels like a bug if Go doesn't support it, I think many people will have the same feeling, just like this ticket #973 (comment) The idea is pretty static. For example |
FWIW, in terms of readability and functionality that is familiar to me from other languages, Python supports expanding an argument list/tuple if it is after the positional args: I'm not familiar with seeing it before positional args. |
I think it's clear why a variadic argument can only be the last argument: because otherwise it would be hard to see where the variadic arguments ended. But I'm not suggesting that this idea can be abused. I'm suggesting that it seems like a special case, and special cases make the language harder to understand. |
No matter a, b, c = foo()
bar(0, a, b, c) vs bar(0, foo()) |
@ysmod I appreciate you’re passionate about this topic but please tone down the hyperbole a bit. Ian has explained the rationale behind the current logic, perhaps it is beneficial to examine how Situations where a function which returns so many parameters that store them temporarily becomes arduous. If that underlying design issue is addressed, maybe the need to add additional cases the argument passing can be avoided. |
@davecheney Updated the words to make it less hyperbole, will be careful next time.
One thing I can come up with is math. It's hard to abstract math tuples into named structs to reduce return values, that's why python or other languages support tuples well. Naming is always one of the hardest problems for programming. |
I agree that sometimes the nature of the problem calls for many return parameters, but I argue that this isn’t the general case, and for a specific case there are always alternatives like returning a structure, returning an anonymous structure, converting the function to a method and capturing the context as an object, and so on. |
This is what Go wants to avoid, too many ways to get around a simple problem. It will be great if the language itself supports it so that we can reduce them into one simple style. |
I offer that this may not be a general problem affecting the majority of applications of Go. |
The Idea of Go generally seems to minimise having multiply ways/styles to achieve something. Instead of reducing the styles for returning complex information from a function and passing it to the next function this proposal will add one more way to pass information without extra variable declarations. The other existing options are not taken away and therefore there is no overall reduction of styles unless the new style is enforced. Not everything will be passed as multiple return values and passing in structures will still continue to be used because in some cases it makes more sense to pass a structure. Sometimes it is warranted to provide an alternative to a complex and easily to get wrong mechanism, that is generally useful but for a specific common case far from ideal. To me this doesn't seem such a case as assigning to variables first is simple enough. One added readability concern is that before I can easily deduce from |
Yes it often confused me that why |
have you thought about how this will be implemented? |
Per discussion above, this is a likely decline. Leaving open for four weeks for final comments. |
No further discussion. |
description:
I did some research, but can't find a similar issue, so I opened a new one.
Sometimes we really want to use the returned values as the input of another function directly without having to use tmp vars.
For example:
It will be great if we can do this:
It's useful for simple debugging:
We already only allow variadic arguments as last arguments, like this:
So I think it makes sense for people to support this kind of feature.
The idea is pretty static. For example
func foo(int, string, int)
can only accept functions likefunc bar() (string, int)
. I feel the proposal is too hard to be abused. If you can give me some examples of how to abuse it, that will be great.I think this language feature doesn't break the GO 1, and won't have an impact on compilation performance.
Here a real-world use case might help you understand it better:
Go already supports it, people use it every day, like this:
My proposal just makes it more intuitive. So we can easily do things like:
So I don't have to implement a lot of guard types.
The text was updated successfully, but these errors were encountered: