4 ms·
Java is not an example of a forward thinking language anymore. It has lagged behind C# in every major feature pretty much since C# arrived in 2000. The JVM has
by lwansbrough 8y ago
Java is not an example of a forward thinking language anymore. It has lagged behind C# in every major feature pretty much since C# arrived in 2000. The JVM has had solid performance improvements since forever, and may still be faster than the CLR, but the JVM still has some pretty glaring shortcomings coming from the .NET world. For example, Java generics (and their underlying implementation in the JVM) suffer from type erasure which makes for an awful developer experience in many scenarios. Java/JVM's story for asynchronous code is also pretty pathetic. This is stuff I don't even think about anymore when writing C# but I groan every time I have to do any "modern" programming in Java.
- bad_user 8y agoMy opinion is from the other side of the fence ... type erasure is perceived as a weakness of Java, however I believe it is one of JVM's best features, because it didn't cripple its runtime for other languages, this being one of the reasons for why other languages have been flourishing on the JVM (that and the tooling and the open source culture). To understand why, we need to talk about 2 separate things: --- 1. Specialization is important for performance and when speaking of .NET, specialization for value types is subsumed in type erasure, but that's not necessarily the case. You can have compiler-driven or even runtime-driven specialization without reification. In Scala for example we've had the "@specialize" annotation for a long time, with the compiler being able to specialize generic code just fine. It's not perfect, a better implementation eventually happened in Miniboxing [1] but it withered away due to lack of interest and the ongoing work happening in Dotty / Scala 3 and its newer TASTY distribution format, which should make specialization easier to accomplish. Also there is on-going work to bring value types to the JVM and it's happening: http://mail.openjdk.java.net/pipermail/valhalla-spec-experts/2018-May/000618.html http://mail.openjdk.java.net/pipermail/valhalla-spec-experts... That said having specialization is pretty cool for fine control of the memory layout and Java developers have to resort to a lot of unsafe hacks for achieving the same thing. But if that cost was paid such that languages like Scala or Haskell could happen on top of the JVM, until they figure out how to do it such that everybody benefits, I think it was a cost worth paying. Also consider that the lack of specialization forced the JVM 's engineers to get creative in other areas. For example the JVM has always been great at inlining code at runtime, even for megamorphic call sites. And the new GraalVM has super impressive abilities to eliminate boxing at runtime, which works for dynamic languages too: https://www.graalvm.org/ https://www.graalvm.org/ --- 2. Reification is in fact about adding info about type parameters at runtime. This aids in using reflection to make a difference between List<int> and List<string>, but people miss the forest from the trees. As a matter of fact such reflection is only needed because languages like Java or C# have very weak static type systems, compared with other languages in the ML family. With an expressive type system, you never need reflection capabilities. In Haskell for example the question of whether something is a List<string> or List<int> never, ever happens. In Scala you sometimes need it, but much rarely and you can get it via a compiler-generated `ClassTag`, which is actually a much better approach, because it makes it clear in the signature, this being compile-time reflection. People also like being able to do "new T", however that need completely goes away via proper support for type classes, which both Haskell and Scala have, this being another special purpose band-aid. And reification is actually a bad feature to have in the runtime, because it makes it hard for languages to support higher-kinded types, or to build dynamic languages. F# does not do higher-kinded types and is less expressive for that reason than OCaml, Scala or Haskell and the primary reason for why it doesn't do higher-kinded types is because it would have to do type erasure by itself, thus forgoing the performance benefits and the interoperability it has with C#. Ironically it is support for higher-kinded types in a language that increases its expressive capabilities to the point that you no longer need runtime reflection. In other words ... you're blaming Java for not having a band-aid that happened in C# due to their static type system being basically unsound and thus needing runtime guards and reflection. You quickly get over this once you'll start using a more expressive language ;-) [1] http://scala-miniboxing.org/ http://scala-miniboxing.org/
- lwansbrough 8y agoI don’t know about all that in all honesty. I’m not a language designer so I suppose I don’t care about the why. All I know is Java is really bad at fulfilling my generic typing needs. Pragmatism is really important for languages, because without it all you have is a complicated excuse for a bad user experience. It’s sort of like how if you were to optimize English by cutting out redundant letters and combining words instead of making new words, you basically end up with German, which many English speakers would agree is not as nice a language to look at. (Germans may disagree of course because they’re used to it.)
- bad_user 8y agoI understand your point, however people complaining about Java are complaining about the language instead of the platform and the platform has evolved to support multiple languages. Scala, Kotlin, Clojure, Eta (Haskell), JRuby are the ones I care about and they've been flourishing. I'm a pragmatic at heart btw, but pragmatism sometimes leads to ignorance. It's important to see what's available on the other side of the fence without bringing the preconceptions bag with you. Because you can then actually use the metaphorical "best tool for the job". It's what I'm doing myself, or at least trying and .NET is without a doubt evolving in a direction I like. And I can also write entire paragraphs of what's better on .NET, I just don't find the generics reification to be one of those things.
- bpicolo 8y agoIs the suggestion that those languages can't easily written on CLR? There's a direct, maintained (by the one-man-army that is https://github.com/dmiller https://github.com/dmiller) port of Clojure to the CLR: https://github.com/clojure/clojure-clr https://github.com/clojure/clojure-clr
- solarkraft 8y agoThis means that C# could be ported to the JVM, doesn't it?