Facilitating the Spread of Knowledge and Innovation in Professional Software Development

Write for InfoQ


Choose your language

InfoQ Homepage News Go Contracts Will Enable Generic Programming

Go Contracts Will Enable Generic Programming

This item in japanese

A new draft to add support for generic programming to Go is centered around the concept of contracts, which are used to constrain type parameters to types and functions. The draft also introduces type inference to simplify the use of generic types and functions by allowing developers to omit types in many cases.

Authored by Google engineer Ian Lance Taylor and Go co-creator Robert Griesemer, the new proposal aims to extend Go syntax with parametric polimorphism. This allows to write functions and types that are able to handle values independently from their actual types, provided they share some structural properties. Although Go uses the term generics, the draft authors warn, they should not be confused with what the term generics names in languages such as C++, C#, Java, or Rust.

In short, this is how you will be able to define and call a generic Reverse function in Go:

func Reverse (type Element) (s []Element) {
    first := 0
    last := len(s) - 1
    for first < last {
        s[first], s[last] = s[last], s[first]

As you can see, Reverse handles a list of generic Element values that support assignment. When calling the function, you specify both the actual arguments and the type of values in the list, although in many cases you will be allowed to omit the type and just write Reverse(s), since s will already imply the Element type.

Type parameters such as Element in the example above are like any other types in Go. As mentioned, Reverse only requires that Element supports assignment, which is true of any Go type, so we did not need to specify a contract for it. A contract in Go is specified by listing the types that comply with it. For example, if we wanted to define a Min operation, we could make it generic to all types that provide a < operator, defined in the standard library. This relation could be expressed through an Ordered contract like in the following example:

contract Ordered(T) {
    T int, int8, int16, int32, int64,
        uint, uint8, uint16, uint32, uint64, uintptr,
        float32, float64,

Once we have this, a generic Min function can be written like:

func Min (type T Ordered) (a, b T) T {
    if a < b {
        return a
    return b

There are a few additional cases you will need to take into account, such as using contracts with methods and contracts using multiple type parameters, but the basic idea presented here remains unchanged. More interesting seems to recall here the kind of reasoning that went into shaping the current generics draft design for Go. In particular, Taylor mentions the desirability of a design where complexity falls on the writer of generic code, rather than on its users; the value of letting writer and users of generic code work independently; the need to both reduce build times and achieve fast execution times; and, finally, preserving the language clarity and simplicity. All those properties went into the current draft for generics and should be granted by any generics proposal for Go, Taylor says.

The draft here described does not have a reference implementation yet, which is a key requirement to be able to play with the new language feature and try it out in practice. This will be the next step in Go generics evolution. When such an implementation will be available, developers will be able to assess the proposal and make sure it enables writing the kind of generic code they are envisioning and to provide their feedback.

Rate this Article