Erased generics are awesome. Without erasure interop and code sharing among languages with different variance strategies is severely hampered. It's because Java erases generics (for subclassable reference types) that Java, Kotlin and Clojure can all share the same data structures without any runtime conversions.
I imagine it would help to keep binary size and compile times down too, though I don't know by how much.
I wonder if C++ compilers "collapse" things like `vector<Foo⋆>` and `vector<Bar⋆>` (or even `vector<size_t>`) if they can figure out that all of their respective methods end up generating the same machine code... Maybe not?
(Stars because I can't seem to escape asterisks properly...)
This is a fairly common optimization that is normally performed by the linker. [0] is a blog entry that describes Microsoft’s implementation of identical function merging.
Ooh, really cool. The comment about function-pointer comparisons was a pretty funny ramification I hadn't considered too. Real "wtf" debugging case I bet.
I wonder what the standard says about it, what the linker can/could typically prove is "safe", and what performance/size changes are seen in practice.
The paper Safe ICF in Gold[0] says that they get between 4 to 7% savings on code size. A safer version that omits functions that have their address taken was 97% as effective.
The talk Diet Templates[1] has some suggestions for how to reduce template bloat.
You want to erase generics because you don't want to bake a specific variance model into your runtime. Erasing generics allows languages with different variance (e.g. Java, Kotlin and Clojure) to share code and data structures. This is not an issue for generics of non-subtypable types, which is why generics of the forthcoming value types will be specialized rather than erased.