Martin Sulzmann
Generic methods are not allowed to introduce type bounds
Methods are not allowed to introduce type parameters
The use of type sets is strictly limited to built-in primitives
The use of type assertions in combination with generics is somewhat limited
Comparable cannot be defined for user data types
The current implementation does not quite follow the design that has been described in Featherweight Go (appeared in OOPSLA’21).
For example, if we want to make pairs showable, the “Show” constraint needs to be included in the definition of pairs.
type pair[T Show, S Show] struct {
left T
right S
}
func (this pair[T,S]) show() string {
return "(" + this.left.show() + "," + this.right.show() + ")"
}This implies that we can only build pairs whose components are showable.
The design proposed in Featherweight Go allows for the following (more flexible) program code.
type ppair[T any, S any] struct {
left T
right S
}
func (this ppair[T Show,S Show]) show() string {
return "(" + this.left.show() + "," + this.right.show() + ")"
}However, the above method definition is rejected by the current Go compiler (tested against Go 1.24).
The following Go playground provides more details:
Here is a sketch of an CML style “event” library for Go.
type Event[T any] chan T
// More general but currently not legal in Go.
// func (e Event[T]) wrap[S any](w func(T) S) Event[S] {
func (e Event[T]) wrap(w func(T) T) Event[T] {
f := make(chan T)
go func() {
f <- w(<-e)
}()
return f
}As commented in the above code. The more general type signature is not accepted by Go. Similar examples are libraries for futures/promises, …
The following is okay.
The following is not okay.
We assume that the appropriate method definitions are provided but the Go compiler complains “x.show undefined (type T has no field or method show)”
This seems surprising because Go’s monomorphization method can be easily applied to `showOnlyOnOffandPair’.
Once you have generics, you might not want to use type assertions at all! However, there may be reasons use them (reflection, …).
The following code is valid.
The following code is invalid.
The Go compiler reports:
invalid operation: cannot use type assertion on type parameter value x (variable of type T constrained by any)
But there is no real reason why both shouldn’t be accepted.
The full example can be found on the Go Playground
The key of a map must be comparable. Unfortunately, it is not possible to sets (represented as a map) as keys.
type Lockset map[Lock]bool
/*
type Lockset struct {
m map[Lock]bool
}
type Deps map[Lock]map[Lockset][]Evt
*/In languages such as C++/Haskell/Haskell, we can easily implement “==” for maps and make “any” type comparable.
The following Go playground gives some workaround.