# The many type equations

## 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)),
}
``````

See it in the playground

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``, …)` where `f` or a function argument `a``i` is a generic function:

Each pair `(a``i``, p``i``)` of corresponding function arguments and parameters where `a``i` is not an untyped constant yields an equation `typeof(p``i``) ≡``A`` typeof(a``i``)`.

If `a``i` is an untyped constant `c``j`, and `typeof(p``i``)` is a bound type parameter `P``k`, the pair `(c``j``, P``k``)` is collected separately from the type equations.

• For an assignment `v = f` of a generic function `f` to a (non-generic) variable `v` of function type: `typeof(v) ≡``A`` typeof(f)`.

• For a return statement `return …, f, …` where `f` is a generic function returned as a result to a (non-generic) result variable `r` of function type: `typeof(r) ≡``A`` typeof(f)`.

Additionally, each type parameter `P``k` and corresponding type constraint `C``k` yields the type equation `P``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