4 ms·
> First of all, Java's generics are already superior to C#'s. We've exchanged the minor inconvenience of not being able to have overloads that erase to the same
by BoorishBears 4y ago
> First of all, Java's generics are already superior to C#'s. We've exchanged the minor inconvenience of not being able to have overloads that erase to the same type with the ability to support multiple variance strategies rather than one that's baked into the runtime.
Working on the JDK I'm sure you're aware just how revisionist that take is: we got the version of generics that landed because of backwards compatibility concerns.
One of the key selling points going from Pizza to GJ was that the result ran on then current JVM targets without modification.
https://jcp.org/en/jsr/detail?id=14 https://jcp.org/en/jsr/detail?id=14
> C1) Upward compatibility with existing code. Pre-existing code must work on the new system. This implies not only upward compatibility of the class file format, but also interoperability of old applications with parameterized versions of pre-existing libraries, in particular those used in the platform library and in standard extensions.
> C2) Upward source compatibility. It should be possible to compile essentially all existing Java language programs with the new system.
Interop came at the expense of Java (not the JVM) having a worse generics story, since the incredibly onerous constraint of "works with parameterized versions of pre-existing libraries" forced other languages to then go and reinvent the exact same wheel in different ways.
-
> We've also added virtual threads years after C# had async/await, and now they're the ones stuck with that inferior solution, which we'll remain in the ecosystem even if and when they add user-mode threads.
"Kingdoms to demolish" refers to changing generics, but there are "kingdoms" have been built that wouldn't be demolished: they still represent a lot of throwaway work from putting off attacking the problem. Case in point, the post we're commenting under.
Nullability specifically is much more subject to the part you left out: "And if you fix it, it'll be years before it trickles down to a large portion of devs who don't get to work at the bleeding edge, or even near the edge."
-
At the end of the day it's always been a tradeoff between backwards compatibility, timeliness, and correctness, but when I switch between Java specifically and C# specifically (not the JVM and the CLR) I find C# did an amazing job providing value upfront rather than hand wringing, and is not nearly as worse off for it as this comment would imply.
I mean you're looking down on async/await, but it came out a decade ago while Loom is just landing. I guess you're trying to paint that decade of development as "weighing down" whatever .NET comes out with because it'll still exist, but that seems like a stretch at best.
Java had no async/await story and will get a very good alternative. C# had an async/await story and will get an improved alternative (it's already in the experimentation stage according to the .NET team). I'd just much rather have the latter?
- pron 4y ago> we got the version of generics that landed because of backwards compatibility concerns. We got the version of generics because of the need for two languages with different variance strategies -- Java 1.4 and Java 5 -- to be compatible, and so precluded baking a particular variance strategy into the runtime. It is true that the goal at the time wasn't to support, say, Scala or Clojure or Ruby specifically, but why does it matter? > forced other languages to then go and reinvent the exact same wheel in different ways. I don't think so. Both untyped languages like Clojure and Ruby, as well as existing typed languages such as Haskell, have been ported to the Java platform. Erasure, BTW, is a pretty standard strategy. Even Haskell does not distinguish at runtime between List Int and List String. > Nullability specifically is much more subject to the part you left out: "And if you fix it, it'll be years before it trickles down to a large portion of devs who don't get to work at the bleeding edge, or even near the edge." So what? Java is likely to be one of the world's most popular languages 20 years from now. Who would care if we wait to do things right, especially as it worked very well for Java so far. Who cares now that lambdas were in Java 8 and not Java 5? As for C# vs Java, there's no doubt some developers prefer one over the other -- for some it's Java, for others C# -- but I see absolutely no reason for Java to adopt C#'s strategy. Even if you don't think it's any worse, it's certainly hasn't proven to be better. Those who prefer C#'s approach already use either it or Kotlin, so we've got them covered on the Java platform, too.
- unscaled 4y ago> Erasure, BTW, is a pretty standard strategy. Even Haskell does not distinguish at runtime between List Int and List String. Haskell doesn't do overloading and reflection, so for Haskell type erasure is a pure implementation detail. It doesn't leak out to the programmer.
- pron 4y agoYes, which is why in Java the cost isn't free but it's still rather low. Of course, the calculus has changed due to memory hierarchies, which is why Valhalla brings with it specialisation for value types (that outweighs the benefits of erasure for those types, but they're not variant, so it doesn't require baking a variance model into the VM).