Go

Why doesn't Go allow type parameters on methods? What do you do instead?

Question 124HardGo 1.22 to 1.25

Methods can use their receiver type's parameters, but a method cannot declare new type parameters of its own. func (l List[T]) Map[U any](f func(T) U) List[U] is illegal.

The reason is interface satisfaction and implementation. Methods are found dynamically, through interfaces and reflection. Suppose a generic method could satisfy an interface method such as Map[U any](...). A call through the interface would then need an instantiation for a U the compiler never saw at compile time. Only a JIT or boxing everything would make that possible, and Go's compile-time stenciling model does not do either. So the designers disallowed it, and generic interface methods too.

type List[T any] struct{ items []T }

// OK: uses receiver's T
func (l *List[T]) Push(v T) { l.items = append(l.items, v) }

// Workaround: top-level function
func MapList[T, U any](l *List[T], f func(T) U) *List[U] {
    out := &List[U]{items: make([]U, 0, len(l.items))}
    for _, v := range l.items {
        out.items = append(out.items, f(v))
    }
    return out
}

This is why the standard library exposes helpers such as slices.Index and maps.Keys as functions and not as methods, and why fluent chains like list.Filter().Map() are not idiomatic Go. You can also put the extra parameter on the type (Mapper[T, U]), but a free function is usually cleaner.

More on Generics

All 36 Generics questions