Partial type argument lists

January 3, 2024


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

See it in the playground.

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

Share this

Direct to your inbox, daily. I respect your privacy .

Unsure? Browse the archive .