The no-generic-methods limitation has been on my mind lately, as I’ve been thinking about how to address it in the Go implementation of Cap’n Proto when we add generics support. My use case is sortof annoyingly circular though: I want support for generics (and generic methods) because the schema language already has them. Right now we just map generics in the schema language to capnp.Ptr (some value of unknown type). I might just do generics for types but keep method type parameters as-is for now, but it would be nice to find a way to support them.
Not sure about any “official” reason, but it’s likely because it would greatly complicate Go’s interface mechanism. In Go, you can perform a “type-assertion” on an interface object to effectively down-cast to another interface. This is a runtime operation that will materalize a method table. After that point, method calls are normal CPU-level indirect function calls. There is no further dynamic method resolution. If the methods were to become generic, that would make the specific call sites dynamically polymorphic. This would substantially impact the performance characteristics of a lot of code that expects to be able to have control over where and when interface resolution occurs. This is in contrast to a typical OOP language, where method resolution is always late-bound. In Java, for example, down-casting to an interface will let you move the instanceof check earlier, but actually invoking methods on those interface references will still be virtual calls, subject to the object’s method dispatch chain. To make that fast requires JIT-like features, such as a polymorphic inline cache.
The no-generic-methods limitation has been on my mind lately, as I’ve been thinking about how to address it in the Go implementation of Cap’n Proto when we add generics support. My use case is sortof annoyingly circular though: I want support for generics (and generic methods) because the schema language already has them. Right now we just map generics in the schema language to capnp.Ptr (some value of unknown type). I might just do generics for types but keep method type parameters as-is for now, but it would be nice to find a way to support them.
Hm. Why no type parameters to methods in Go? Even Zig supports this, albeit only at comptime as I recall it.
Not sure about any “official” reason, but it’s likely because it would greatly complicate Go’s interface mechanism. In Go, you can perform a “type-assertion” on an interface object to effectively down-cast to another interface. This is a runtime operation that will materalize a method table. After that point, method calls are normal CPU-level indirect function calls. There is no further dynamic method resolution. If the methods were to become generic, that would make the specific call sites dynamically polymorphic. This would substantially impact the performance characteristics of a lot of code that expects to be able to have control over where and when interface resolution occurs. This is in contrast to a typical OOP language, where method resolution is always late-bound. In Java, for example, down-casting to an interface will let you move the instanceof check earlier, but actually invoking methods on those interface references will still be virtual calls, subject to the object’s method dispatch chain. To make that fast requires JIT-like features, such as a polymorphic inline cache.