Generic function declarations

August 22, 2023

Function declarations

If the function declaration specifies type parameters, the function name denotes a generic function. A generic function must be instantiated before it can be called or used as a value.

func min[T ~int|~float64](x, y T) T {
	if x < y {
		return x
	}
	return y
}

We’ve mentioned instantiation before, but it will be covered in depth later. For now, it’s enough to show an example of what the spec means can’t be done without instantiating a generic function:

func notGeneric(a int) int { /* ... */ }

func generic[T int|float64](a T) T { /* ... */ }

var x = notGeneric // valid, x is of type func(int) int

var y = generic // invalid, until the function is instantiated, T's type is unknown, thus the function's type is undetermined

var z = generic[int] // valid, z is of type func(int) int

See this in the playground

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 .

Related Content


Generic functions as operands

Operands … An operand name denoting a generic function may be followed by a list of type arguments; the resulting operand is an instantiated function. So first off, recall that an operand may be a function literal: var x = func() { /* ... */ } Or a variable that represents a function: var F = func() { /* ... */ } var f = F // <--- `F` is a variable that represents a function Or another expression that evaluates to a function:


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.


When function instantiations can be inferred

A quick update on my livestream: It’s on hold until February, as my family and I made a bit of a last-minute trip to visit family for the month of January, so I won’t be in my studio for a while. Instantiations … When using a generic function, type arguments may be provided explicitly, or they may be partially or completely inferred from the context in which the function is used.

Get daily content like this in your inbox!

Subscribe