This sounds far-fetched to me, partly because of the nontrivial technical differences between Java and Go and partly because of the politics surrounding Oracle’s ownership of Java and the way Oracle quashes community efforts.
Value types, interior pointers, multiple levels of pointers, slices, and radically different indirect dispatch semantics are just a few things that Go has that Java doesn’t. These aren’t things that you can staple to Java. Java is more than syntax, it’s the semantics of the JVM and its object system, which should only be extended in a backwards-compatible way.
So I’m gonna say that the reason Go exists is exactly because the creators didn’t want to burn down Java and start over. It turns out that you can create a new language without burning anything down. There is also C# and the various nontrivial differences between C# and Java, like value types and type erasure in generics.
There are plenty of languages which exist side-by-side with Java in the JVM: Clojure, Kotlin, and Scala to name three. These all have their differences but they’re all designed specifically with the JVM in mind. Go isn’t.
Go instead decided to go with a minimal runtime with a one-two order worse GC than any you can find in the JVM, which will result in inferior throughput in actual world benchmarks.
While generating less garbage decreases the load on the GC so it can sometimes get away with it, complex server apps will not fall into this category. So actually, I really don’t see much value in go, other than the “you can throw as many developer at it, because they can’t really step on each other’s foot” which is actually great for what it was created for.
> ...which will result in inferior throughput in actual world benchmarks...
You're telling me that Go's garbage collector, which is optimized for low latency, has worse throughput than the JVM's default allocator, which is optimized for high throughput?
Most garbage collectors are either designed for low latency or high throughput. You cannot optimize for both. The choice for high throughput makes sense for batch programs, like compilers, command-line tools, generating analytics reports, etc. Choosing low-latency makes sense for web services and the backend services behind them.
As fanout increases, the GC latency in backend services becomes much more important.
I think the world was almost tolerable before Go and Rust came along. We already had too many languages even before those two, but at least there was a clear leader: Java. Nowadays the market is completely fragmented.
I think all languages do suffer from their initial design. And spend 5-years iteration to circumventing them.
Java will have proper asynchronous management in 5 years, Go will have generics in 5 years, Rust will have a garbage collector variant in 5 years, Python and JavaScript will have full multithreading in 5 years.
In the end, no language is catching the whole problematic and solve it at once.
So there is a programming language fatigue.
PS: when I say that things happen within a timeframe of 5 years, it includes the time to deliver the feature in the language, and people to massively adopt it, and new developped code to include it in mass.
Every new language is an attempt to fix some problems in the existing languages but at the same time be simple to learn and use. But the problem-space of programming is very complex. So while a new language does something better than some existing languages the language designers do not foresee all problems that may arise in actual use.
Maybe a way to proceed would be to have a common set of code which every new language would try to rewrite, and thus see how much better it is, or is not, than the existing ones. Comparative analysis.
Exactly right. Each new language thinks they've simplified and solved problems, but in the end they end up having to solve the same old problems that have already been solved decades earlier lots of times.
Rebuilding similar functionality maybe but who's actually porting between languages?
Plus code can already be shared with various bindings. Lately there's been a big push with "microservices" or generally networked architectures so different components built in entirely different stacks can still interoperate just fine.
Value types, interior pointers, multiple levels of pointers, slices, and radically different indirect dispatch semantics are just a few things that Go has that Java doesn’t. These aren’t things that you can staple to Java. Java is more than syntax, it’s the semantics of the JVM and its object system, which should only be extended in a backwards-compatible way.
So I’m gonna say that the reason Go exists is exactly because the creators didn’t want to burn down Java and start over. It turns out that you can create a new language without burning anything down. There is also C# and the various nontrivial differences between C# and Java, like value types and type erasure in generics.
There are plenty of languages which exist side-by-side with Java in the JVM: Clojure, Kotlin, and Scala to name three. These all have their differences but they’re all designed specifically with the JVM in mind. Go isn’t.