> You can only make tradeoffs. In this case, Java's sacrificing time.
When you have billions of LOC, and take backward compatibility seriously, then that's a very valid approach. Furthermore, we've seen the Java team pick up cadence recently since switching to twice a year releases.
> They've historically shown poor taste in the features they've chosen,
Quite disagree. Which features are you talking about? They've shown very good taste in how records and pattern matching have been implemented for example. An also not jumping on the async bandwagon and opting for virtual threads instead.
> Already? Ten years later! Time matters.
Java had other approaches for dealing with heavyily asynchronous code, but it wasn't as ergonomic. And honestly speaking, the JVM already gives you access to native threads (something that neither golang (only "goroutines") nor python (GIL) for example offer), that unless you're doing heavy IO bound work, it's a non-issue to begin with.
> Go was built with its concurrency solution in mind
That is the claim, but in practice it is quite error prone. I was following golang from pre-release, and I voiced concerns about not having a way to declare immutable values (or at least something similar to C++'s const), but they didn't seem to care. Of course it came to bite them back[1]. Passing channels everywhere is tedious and verbose, and doesn't make it clear what the code is doing at first glance. Futures/Tasks are an easier abstraction to deal with, but of course golang didn't have generics until recently, and they still don't offer a future package.
> I've been hearing this for a while, has it been a decade yet?
You can follow the valhalla project to see what they're up to. It's sufficient to say that the pace picked up significantly on these large projects since switching to a twice a year cadence.
> You can't be serious. Complaining about another language's null problems from the perspective of Java?
Having worked on large golang codebases, I've seen first hand the issues that zero types cause in practice. At least a nullable in Java would throw an NPE instead of silently passing through the system and ending up with completely arbitrary behavior that is challenging to track down. Not to mention that you can use annotations to denote @NotNull in Java, something that golang doesn't have.
> It's a wash most of the time AFAIK. Unless we do the classic Java benchmark trick of ignoring memory usage.
Memory usage should improve with value types, but it also seems that people don't configure their JVMs properly (things like Xmx). In any case, they've also modified G1GC (and probably one or two more) to more aggressively release unused memory back to the OS).
[1] https://www.uber.com/blog/data-race-patterns-in-go/