3 ms·
Non-reified generics is the feature that allows different JVM languages to interoperate much more easily and share data structures. If you look at the CLR, inte
by pron 8y ago
Non-reified generics is the feature that allows different JVM languages to interoperate much more easily and share data structures. If you look at the CLR, interop there is much messier, largely due to this. The reason is that if reference-type generics were reified, then the JVM must know the subtyping relationship between such different types, and different languages have very different variance strategies. This limitation does not apply to types that cannot be subtyped, which is why value type generics can (and will) be reified.
In exchange, you pay with a minor nuisance: mostly the inability to overload methods with the same erased types. I think most would agree that having a truly polyglot VM that allows different languages to enjoy the data structures written in other languages is much more important.
- bradleyjg 8y agoIt’s an interesting trade-off. It makes java a somewhat weaker language but the jvm a better platform. At the time the decision was made, probably no one was thinking of the jvm as polyglot platform. So there was a decision whose chief benefit was only revealed in retrospect.
- bunderbunder 8y agoIt's also possibly an unnecessary trade-off. Scala, for example, has something akin to reified generics, without any support from the JVM itself. It also allows for a decent level of interop with other JVM languages, though of course all you can really "export" to other languages is the least common denominator semantics required by the JVM. Java could theoretically do something similar: Maintain type information that is visible to Java at compile- and run-time, while still compiling to code that is consumable from other languages without too much hassle. Really, personally, I only care about it being available at compile time. Haskell, for example, erases types much more aggressively than Java does, while also maintaining a high level of type safety. I guess I don't know that it's backwards compatibility on the JVM that bothers me so much as Java's tendency to think of itself as being little more than a JVM macro assembler with C-like syntax.
- pron 8y agoThat's not so simple. The class file, I believe, does have the generic instance at the use site, but then if you could have two overloads, foo(List<String>) and foo(List<Integer>), which would you call if you use a raw type (either in Java or from other languages). It's not that Java is a JVM macro assembler so much that there is not much to be gained from this feature given the rest of Java, and Java has a very different design philosophy from Scala, as it aims at a different audience. If and Java evolves in that direction, perhaps this feature would change. In the meantime, those who like Scala can use Scala.
- bunderbunder 8y agoThis feels to me more like a failure of imagination than a technical impossibility. C#, for example, handles some things like this by exporting a function with a special name in the compiled modules. Java could do the same - handle the overload by having them be two different methods named something like foo__String() and foo__Integer() on the back end. The naming may not be beautiful, but I think that, if you do it right (for starters, try to use more readable naming conventions than Scala does), it can make for a pretty sane user experience for consumers who are using different languages. Naturally, the best practice would also be to design so that the API remains clean for packages that are meant to be consumed by multiple JVM languages. I also want to point out that having a type system with a stronger handle on generics is about more than just ergonomics when overloading methods. As another example, Java's story for auto-mapping libraries (serialization/deserialization, lighweight ORM, stuff like that) is materially hindered by the inability to express things like "List<MyDataType>.class". And those sorts of things do have a material impact on developer productivity - when I'm working in Java, I find that I spend an inordinate amount of time writing, maintaining and code reviewing all the extra glue code that needs to be written to handle tasks that other languages make almost effortless.
- pron 8y ago> This feels to me more like a failure of imagination than a technical impossibility. It's not the lack of possible solutions, but more of a design philosophy. > is materially hindered by the inability to express things like "List<MyDataType>.class See Guava's TypeToken https://google.github.io/guava/releases/25.0-jre/api/docs/com/google/common/reflect/TypeToken.html https://google.github.io/guava/releases/25.0-jre/api/docs/co... > I find that I spend an inordinate amount of time writing, maintaining and code reviewing all the extra glue code that needs to be written to handle tasks that other languages make almost effortless. Which is why the Java ecosystem offers a nice selection of languages to match almost everyone's taste. Many people like Java and feel productive using it, and those who don't can enjoy the great polyglot interop afforded by, among other things, generic type erasure.
- tigershark 8y agoI don’t really see any interoperability difficulty at all between C# and F# on the CLR, can you please be more specific? As far as I remember instead interoperability between Java and Scala was quite a pain because of the different data structures.
- pron 8y agoThat's because both were designed to specifically work with how the platform is designed. But compare Python/C# and, say Python/Java or Clojure/Java interop and code sharing.
- tigershark 8y agoOk, then are you saying that the problem is that the authors of iron Python didn’t spend as much time and effort to integrate it in the .NET platform compared to the work that has been done with OCAML? From what I know it was actually Don Syme, the creator of F#, to bring non-erased generics in .NET. And if I remember correctly without his work on the generics it would have been more painful to have a nice interop between C# and F#. This seems quite at odds with your assertion that on the contrary erased generics make easier the interop between different languages on the same JVM/CLR.
- pron 8y agoAll I can say is -- it's complicated. When languages share much in common, then factoring stuff into the runtime can make things easier, but when they're very different, the more language-level assumptions you bake into the runtime the harder it is to share code. You want to strike a good balance between having a rich runtime that makes it easy to implement languages and not baking too much language semantics into the runtime, to make it easier to share code. In retrospect, I think that the tradeoff of not having generics reified at the JVM, causing a minor nuisance in Java but making code sharing and interop easier across a wide range of languages is a net gain.
- tigershark 8y ago