-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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: spec: allow using spread on arrays in function calls, assignment and return statements #62685
Comments
When used with function arguments, the func main() {
words := [4]string{"choose", "blimp", "sleep", "blue"}
a(words...)
}
func a(w1, w2, w3, w4 string) {
} The above returns the compile error It seems inconsistent to permit that sort of destructuring assignment for return values and "normal" assignments but not for the implied assignments to function parameters in calls. Are you meaning to propose to support this in function call argument lists too? Note that it isn't currently valid to use arrays in that location either. It only works if the argument given is a slice and it's being assigned to a parameter that uses func main() {
words := [4]string{"choose", "blimp", "sleep", "blue"}
a(words[:]...)
}
func a(words ...string) {
} ...but perhaps that was the point you were intending to make in calling out the distinction between slices and arrays in your proposal. |
Indeed, yes. Seems I forgot that use case when I was looking at current code i have. Update above.
I'm wondering if that is actually worth another proposal: allow spread to spread arrays similar to slices where variadic parameters are targetd. In context of this proposal- targeted at arrays- this would rather be equivalent to using it for spreading to a well-known number of identically-typed arguments:
|
Thanks for the extra information, @andig. The specification currently states (in Passing arguments to Given that, I assume that it were made possible to refer to an array directly in that position, like this... func main() {
words := [4]string{"choose", "blimp", "sleep", "blue"}
a(words...) // words is [4]string here, not []string
}
func a(words ...string) {
} ...then the compiler would behave as if the call were Continuing that analogy, let's consider your latest example: func main() {
words := [2]string{"choose", "blimp"}
a(words...)
}
func a(w1, w2 string) {
} Would you say that in this case the compiler would treat the call as if
I think this model of implied assignment of individual indices isn't complete because I assume you'd also want the assignment to fail if there were too many elements. Again with an array that seems trivially decidable at compile time. For slices, would that also be a panic? (I realize that in the original proposal text you have implicitly ruled out using slices by only describing the behavior for arrays. I'm only poking at behavior for slices because in these comments we've been discussing the generalization of |
A further note, based on more spec reading: The slice operation is defined to work both on arrays directly and on pointers to arrays, and so I assume for consistency it would also become valid to place a pointer to an array before |
The proposal targets arrays only as I think we must maintain compile time safety. |
It's an interesting idea but the restriction to arrays means that it won't have many uses. Also, the emoji voting is not in favor. Therefore, this is a likely decline. Leaving open for three weeks for final comments. |
Indeed, I think limiting to only arrays does help rule out some potential runtime panics but it also makes the result considerably less useful, because I think direct use of arrays is relatively uncommon and most Go programs are built to use slices except in some specialized situations such as using a fixed-size array to represent a checksum, and I don't expect it would be useful to destructure those. Somehow making it work for slices would make it more widely-applicable, and that was what interested me in exploring that angle more deeply above, but I think it would also feel a little out of place in Go, since that sort of dynamic dynamically-fallible destructuring is more common in dynamically-typed languages where most mistakes are detected at runtime. That's not the sort of design I'd expect from a language like Go. |
No change in consensus. |
Would you consider yourself a novice, intermediate, or experienced Go programmer?
Experienced
What other languages do you have experience with?
Recently only Go
Would this change make Go easier or harder to learn, and why?
Might be a bit harder to understand why returns don't allow slices
Has this idea, or one like it, been proposed before?
Couldn't find it mentioned. It might clash with discussions of omitting zero values in return statements.
Who does this proposal help, and why?
Reduce amount of code to write
What is the proposed change?
Allow using the spread operator on arrays in function calls, return statements and assignments.
Please describe as precisely as possible the change to the language.
Allow
What would change in the language spec?
The
...
operator would get a new use case.Please also describe the change informally, as in a class teaching Go.
Using the spread operator in
allows assigning or returning a matching number of individual parameters taken from the array of length identical to the number of expected parameters.
Is this change backward compatible?
Yes
Show example code before and after the change.
Before:
After (changed to array since slice wouldn't work):
What is the cost of this proposal? (Every language change has a cost).
Implementation, discussion of slices of known length vs arrays.
How many tools (such as vet, gopls, gofmt, goimports, etc.) would be affected?
?
What is the compile time cost?
?
What is the run time cost?
?
Can you describe a possible implementation?
No
Do you have a prototype? (This is not required.)
No
How would the language spec change?
Orthogonality: how does this change interact or overlap with existing features?
No
Is the goal of this change a performance improvement?
No
Does this affect error handling?
No :)
Is this about generics?
No
The text was updated successfully, but these errors were encountered: