Forked off #58650 per @ianlancetaylor's request
Currently
func Add[T addable](x, y T) T {
return x + y
}
var x = 1 + 2.5
var y = Add(1, 2.5)
assigns x the type float64 but on the next line reports the error default type float64 of 2.5 does not match inferred type int for T.
Go takes the default type based on the literal form before applying type inference so it's the same as writing Add(int(1), float64(2.5)).
In the special case of multiple untyped numeric literals for a single type parameter, type inference should select the "largest" one provided to use as the default type.
("largest" in the sense that complex128 is larger than float64 is larger than int)
template
Author background
- Would you consider yourself a novice, intermediate, or experienced Go programmer? experienced
- What other languages do you have experience with? Many.
Related proposals
- Has this idea, or one like it, been proposed before? not to my knowledge
- If so, how does this proposal differ?
- Does this affect error handling? no
- If so, how does this differ from previous error handling proposals?
- Is this about generics? yes
- If so, how does this relate to the accepted design and other generics proposals? tweaks the inference algorithm
Proposal
- What is the proposed change? see above
- Who does this proposal help, and why? Currently the eagerness to jump to default types makes inference behave more rigidly than the rest of the language. This would loosen the restriction to make both behave the same so there's less to remember.
- Please describe as precisely as possible the change to the language. see above
- What would change in the language spec? inference algorithm
- Please also describe the change informally, as in a class teaching Go. The same explanation that's used to explain the default type of
1 + 2.5
- Is this change backward compatible? yes, all old code would still be admissible, this would just allow code to work that is currently an error
- Breaking the Go 1 compatibility guarantee is a large cost and requires a large benefit.
Show example code before and after the change.
- Before
Add(1.0, 2.5)
- After
Add(1, 2.5)
- Orthogonality: how does this change interact or overlap with existing features? n/a
- Is the goal of this change a performance improvement? no
- If so, what quantifiable improvement should we expect?
- How would we measure it?
Costs
- Would this change make Go easier or harder to learn, and why? Easier as type inference would work the same as regular math expressions.
- What is the cost of this proposal? (Every language change has a cost). change to type inference algorithm/spec
- How many tools (such as vet, gopls, gofmt, goimports, etc.) would be affected? go/types would need to implement the changes in addition to the compiler. Nothing else would need to change that I am aware of.
- What is the compile time cost? extra stage during type inference in corner cases, unlikely to be an issue
- What is the run time cost? none
- Can you describe a possible implementation? no
- Do you have a prototype? (This is not required.) no
Forked off #58650 per @ianlancetaylor's request
Currently
assigns
xthe typefloat64but on the next line reports the errordefault type float64 of 2.5 does not match inferred type int for T.Go takes the default type based on the literal form before applying type inference so it's the same as writing
Add(int(1), float64(2.5)).In the special case of multiple untyped numeric literals for a single type parameter, type inference should select the "largest" one provided to use as the default type.
("largest" in the sense that complex128 is larger than float64 is larger than int)
template
Author background
Related proposals
Proposal
1 + 2.5Show example code before and after the change.
Add(1.0, 2.5)Add(1, 2.5)Costs