# Partial type argument lists

## Instantiations

A partial type argument list cannot be empty; at least the first argument must be present. The list is a prefix of the full list of type arguments, leaving the remaining arguments to be inferred. Loosely speaking, type arguments may be omitted from “right to left”.

``````func apply[S ~[]E, E any](s S, f func(E) E) S { … }

f0 := apply[]                  // illegal: type argument list cannot be empty
f1 := apply[[]int]             // type argument for S explicitly provided, type argument for E inferred
f2 := apply[[]string, string]  // both type arguments explicitly provided

var bytes []byte
r := apply(bytes, func(byte) byte { … })  // both type arguments inferred from the function arguments
``````

Let’s demonstrate this by refering to the example from yesterday. We had the following function:

``````func sum[T ~int | ~float64, R ~int | ~float64](x ...T) R
``````

And could not infer the return type:

``````fmt.Println(sum(1,2,3)) // cannot infer R
``````

This means we must explicitly provide the return type in the call, as illustrated:

``````fmt.Println(sum[int, int](1, 2, 3)) // Success!
``````

But since the return type comes second in the type parameter list, it means we must also explicitly provide the type for `T`, even though it could be inferred. There’s no way to skip over that first type argument:

``````sum[_, int](1, 2, 3)   // Nope
sum[..., int](1, 2, 3) // Nuh-uh
sum[?, int](1, 2, 3)   // No way!
``````

Of course we could re-order the type parameters in the function, if we really care about this:

``````func sum[R ~int | ~float64, T ~int | ~float64](x ...T) R

sum[int](1, 2, 3) // now this is valid
``````

One last note on instantiations before our next topic tomorrow:

For a generic type, all type arguments must always be provided explicitly.

In other words, there’s no way to infer the type parameters for a generic type.

``````type X[T any] []T
x := X{1, 2, 3}      // cannot use generic type X[T any] without instantiation
y := X[int]{1, 2, 3} // valid
``````

Quotes from The Go Programming Language Specification Version of August 2, 2023