Type inference
…
Type inference supports calls of generic functions and assignments of generic functions to (explicitly function-typed) variables.
So just to call out this point, made in passing: You cannot assign the result of a generic function to a generic, non-instantiated type, even if inferrence should be intuitive. Do demonstrate:
type S[T ~int | ~float64] struct {
Value T
}
func sum[V ~int | ~float32](a, b V) V {
return a + b
}
// cannot use generic type S[T ~int | ~float64] without instantiation
x := S{
Value: sum(int(1), int(2)),
}
Even though the type returned from sum()
is obviously int
, we cannot do this assignment. We must instantiate the type S
explicitly:
x := S[int]{
Value: sum(int(1), int(2)),
}
But, we can pass the results of generic functions to other generic functions:
… This includes passing generic functions as arguments to other (possibly also generic) functions, and returning generic functions as results. Type inference operates on a set of equations specific to each of these cases. The equations are as follows (type argument lists are omitted for clarity):
For a function call
f(a
0
, a
1
, …)
wheref
or a function argumenta
i
is a generic function:Each pair
(a
i
, p
i
)
of corresponding function arguments and parameters wherea
i
is not an untyped constant yields an equationtypeof(p
i
) ≡
A
typeof(a
i
)
.If
a
i
is an untyped constantc
j
, andtypeof(p
i
)
is a bound type parameterP
k
, the pair(c
j
, P
k
)
is collected separately from the type equations.For an assignment
v = f
of a generic functionf
to a (non-generic) variablev
of function type:typeof(v) ≡
A
typeof(f)
.For a return statement
return …, f, …
wheref
is a generic function returned as a result to a (non-generic) result variabler
of function type:typeof(r) ≡
A
typeof(f)
.Additionally, each type parameter
P
k
and corresponding type constraintC
k
yields the type equationP
k
≡
C
C
k
.
Are you yawning as much as I am?
In summary, after the entire function call is expanded, we match all the arguments passed to the function (and functions passed to the function), to their associated parameters.
Then we end up with a list of equations of forms similar to:
typeof(v) ≡
A
typeof(f)
typeof(p
1
) ≡
A
typeof(a
1
)
typeof(p
2
) ≡
A
typeof(a
2
)
- etc…
Then we can begin solving the equatoins.
Well, actually not yet… There’s one more small step to consider, first. Tomorrow.
Quotes from The Go Programming Language Specification Version of August 2, 2023