Skip to content

Instantly share code, notes, and snippets.

@changkun
Created August 23, 2021 12:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save changkun/b9cd81a5542730f5297b5aaa940ce610 to your computer and use it in GitHub Desktop.
Save changkun/b9cd81a5542730f5297b5aaa940ce610 to your computer and use it in GitHub Desktop.
Go's Generics Design Evolution

Go's Generics Design Evolution

https://golang.design/s/go2generics

Go 1 (2008-2021)

func MaxInt(a, b int) int {
   if a < b {
       return b
   }
   return a
}
func MaxFloat64(a, b float64) float64 {
   if a < b {
       return b
   }
   return a
}
func MaxUintptr(a, b uintptr) uintptr {
   if a < b {
       return b
   }
   return a
}
...

Type Function (2010)

type Lesser(t) interface {
   Less(t) bool
}

func Max(a, b t type Lesser(t)) t {
   if a.Less(b) {
       return b
   }
   return a
}

Generalized Types 1.0 (2011)

gen [T] type Lesser interface {
   Less(T) bool
}
gen [T Lesser[T]] func Max(a, b T) T {
   if a.Less(b) {
      return b
   }
   return a
}

Generalized Types 2.0 (2013)

gen [T] (
   type Lesser interface {
       Less(T) bool
   }
   func Max(a, b T) T {
       if a.Less(b) {
           return b
       }
       return a
   }
)

Type Parameters 1.0 (2013)

type [T] Lesser interface {
   Less(T) bool
}
func [T] Max(a, b T) T {
   if a.Less(b) {
       return b
   }
   return a
}

//go:generate (2014)

import "github.com/cheekybits/genny/generic"

// cat max.go | genny gen "T=NUMBERS" > max_gen.go
type T generic.Type

func MaxT(less func(a, b T) bool, a, b T) T {
   if less(a, b) {
       return b
   }
   return a
}

First Class Types (2015)

const func Max(a, b gotype) gotype {
   switch a.(type) {
   case int, float64, uintptr:
       if a < b {
           return b
       }
       return a
   default:
       aa, ok := a.(interface{ Less(gotype) bool })
       if !ok {
           panic("a must implements Less")
       }
       if aa.Less(b) {
           return b
       }
       return a
   }
}

Contracts 1.0 (2018)

contract Ordered(x T) {
    x < x
    x > x
    x == x
}
func Max(type T Ordered)(a, b T) T {
    if a < b {
        return b
    }
    return a
}

Contracts 2.0 (2019)

contract Ordered(T) {
    T int, int8, int16, int32, int64,
    uint, uint8, uint16, uint32, uint64, uintptr,
    float32, float64
}
func Max(type T Ordered)(a, b T) T {
    if a < b {
        return b
    }
    return a
}

Type Parameters 2.0 with Type List (2020)

type Integer interface {
    type int, int8, int16, int32, int64,
    uint, uint8, uint16, uint32, uint64, uintptr,
    float32, float64
}
func Max(type T Integer)(a, b T) T {
    if a < b {
        return b
    }
    return a
}

Type Parameters 2.1 with Type List (2020)

type Integer interface {
    type int, int8, int16, int32, int64,
    uint, uint8, uint16, uint32, uint64, uintptr,
    float32, float64
}
func Max[T Integer](a, b T) T {
    if a < b {
        return b
    }
    return a
}

Type Parameters 3.0 with Type Set (2021)

type Integer interface {
    ~int | ~int8 | ~int16 | ~int32 | ~int64 |
    ~uint | ~uint8 | ~uint16 | ~uint32 | ~uint64 | ~uintptr |
    ~float32 | ~float64
}
func Max[T Integer](a, b T) T {
    if a < b {
        return b
    }
    return a
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment