4 ms·
For the same reason why C++ doesn't have virtual function templates. The usual way to implement dynamically dispatched method calls efficiently is with vtables,
by int_19h 2y ago
For the same reason why C++ doesn't have virtual function templates. The usual way to implement dynamically dispatched method calls efficiently is with vtables, but if your method is itself generic, and it can be dispatched through a superclass reference (or interface value in Go), how do you instantiate the implementation and allocate slots in vtable?
C# can do this because it has a JIT and can compile such methods dynamically (and rejig vtable if needed). In an AOT-compiled language like Go, it would either need to treat this pessimistically and instantiate every possible implementation of every method that could be virtually dispatched anywhere in the program, or else it needs to do what Swift does and generate code that is generic at runtime - i.e. pass some kind of type descriptor with information like size of type and everything else that's needed to handle it, and then the code would look at that type descriptor and do the right thing; this works, but it's non-trivial, and generated code is very slow.
- lenkite 2y agoYet C++ is a very flexible language. You have the tools to implement approaches like "stateful metaprogramming" to give you virtual function templates if you really need them. There is nothing (wrt language) that cannot be done with C++.
- pjmlp 2y agoReflection, but it is finally being sorted out.
- neonsunset 2y agoJIT is not a requirement for this and 'GetFoo<T>().Bar<U>()` works just fine under NativeAOT (even if Foo is abstract and Bar is virtual). Indeed this involves expensive lookup for generic virtual methods. It is also not very friendly to NAOT's binary size once you start having many generic instantiations of the type with such method(s). In the case of Go, I'd assume it will require making both its VM and code reachability analysis more complex to make it work, and they decided to simply shift the responsibility and ceremony onto the programmer which is the standard in Go design.