Successful type inference

January 12, 2024

Today we finish up the discussion on type inference. So we’ve now

Type inference

If the two phases are successful, type inference determined a type argument for each bound type parameter:

	Pk ➞ Ak

A type argument Ak may be a composite type, containing other bound type parameters Pk as element types (or even be just another bound type parameter). In a process of repeated simplification, the bound type parameters in each type argument are substituted with the respective type arguments for those type parameters until each type argument is free of bound type parameters.

So in the simple case, our Pk ➞ Ak algorithm results in something like: T ➞ int. But it might be a composite type, too: T ➞ []string or T ➞ struct { Name string; Age int}… or even T ➞ []P, where P is another type parameter for which we need to resolve the equations we just spent the last few days going through.

So this process can repeat…

If type arguments contain cyclic references to themselves through bound type parameters, simplification and thus type inference fails. Otherwise, type inference succeeds.

Yeah… so as we’ve seen before, Go really doesn’t like cyclical references. I like that about Go. 😊

And there we have it… It only took… (let me count…) 5 days to get through this section of the spec on type inference.

Next up: A slog through Type unification. Then on to something a bit more mundane: operators.

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


Exact & loose type unification

Type unification … Unification uses a combination of exact and loose unification depending on whether two types have to be identical, assignment-compatible, or only structurally equal. The respective type unification rules are spelled out in detail in the Appendix. The precise definitions of “exact” and “loose” unification are buried in the appendix, and depend on the specific types involved. In general, I think it’s not terribly inaccurate to say that exact unification applies when the two types are identical, for composite types with identical structure (i.


Type unification

A couple of days ago we saw the spec reference the concept of “type unification”. Today we start through that explanation…. Type unification Type inference solves type equations through type unification. Type unification recursively compares the LHS and RHS types of an equation, where either or both types may be or contain bound type parameters, and looks for type arguments for those type parameters such that the LHS and RHS match (become identical or assignment-compatible, depending on context).


Type switches with generics

More live coding today! Join me! And bring your questions. Type switches … A type parameter or a generic type may be used as a type in a case. If upon instantiation that type turns out to duplicate another entry in the switch, the first matching case is chosen. func f[P any](x any) int { switch x.(type) { case P: return 0 case string: return 1 case []P: return 2 case []byte: return 3 default: return 4 } } var v1 = f[string]("foo") // v1 == 0 var v2 = f[byte]([]byte{}) // v2 == 2 The example included is nice, because it shows two examples of the type parameter P being used: Both the first case (case P) and third (case []P) use the type parameter.

Get daily content like this in your inbox!

Subscribe