> their goals, design philosophy and levels of abstraction are nearly identical
I think it could not be more different. Java APIs (including libs by Sun/IBM/Oracle) is a manifestation of more is less which is exactly opposite of Go.
> Java for more serious server-side software
The seriousness part is only because serious folks (the one who fund projects) prefer Java. I too think this is very important if not the most important part.
> unparalleled monitoring and tooling and more,
I too would need lot of monitoring and tooling if Oracle/OpenJDK GC keeps crapping out for just 10-20GB heaps which is currently the case for us.
For example?
> The seriousness part is only because serious folks (the one who fund projects) prefer Java.
I disagree. There are plenty of design decisions in Go that make it less optimal for very large projects (e.g. dependencies, error handling, generics), but most of all lack of hackability. Go is one of the least hackable languages I've ever encountered, i.e. the only escape-hatch you have when you realize, 5 years into the project, that you need to circumvent some runtime semantics are either source-code instrumentation or hacking on the runtime itself.
> Oracle/OpenJDK GC keeps crapping out for just 10-20GB heaps which is currently the case for us.
There is no way Go's GC wouldn't crap out on you sooner (except maybe in the circumstances that are now addressed as part of Valhalla).
Having said that, I think Go is great, and is a natural fit for anyone who likes the Java philosophy (which is also the Go philosophy)[1]. Some design decisions and some implementation circumstances just make it less suitable for really big stuff.
[1]: Namely, reading comes before writing, no too-clever tricks, and no cutting-edge PL ideas; a "blue collar" language, as Gosling referred to it.
I'm curious. Is there empirical evidence proving that Go is better than Java for small command-line apps, or did you just use your personal judgement to reach this conclusion?
Sure. It doesn't require warmup, it's a little easier to deploy as a standalone executable, and performance is comparable to compiled Java code in programs of this size (you can easily confirm all three claims); those are pretty much the relevant requirements from many command line programs. It's not a property of the language but of its implementation choices (AOT compilation, statically linked runtime), which match the requirements of those kinds of applications better.
Furthermore I think most people reach for Golang in the beginning because they want performance. However I've found it incredibly easy to write unperformant Go.
I think Golang will ultimately be a very important stepping stone in language development in terms of concurrency, type systems, standard libraries, deployability, and many other categories. I think a lot of important programs will be written in it. And ultimately I look forward to how future languages draw from it.
Some may argue that Go's simplicity is a strength. Adding moving parts doesn't always help.
"stepping stone" usually implies progress and Golang was a regression on both fronts, and while its deployment story is ok that's in no small part because it just opts to statically link everything by default, which the field has been going back and forth on basically since the beginning.
Plenty of JSON libraries in plenty of languages have both a function to decode JSON and an object that allows you to decode JSON with some settings. That's not really a Go-specific issue.
If you have time to spare read this: http://blog.paralleluniverse.co/2014/05/01/modern-java/
https://github.com/EnterpriseQualityCoding/FizzBuzzEnterpris...
One just can't write this shit in Go. The language itself precludes it.
It really doesn't, and you could write the exact same thing. Java code doesn't look like that, either (certainly not modern code).
Lack of very basic functions (map, filter, reduce) against slices.
map[string]interface{} is pain to work with (one of the moderately popular libraries I mentioned helps: https://github.com/karlseguin/typed)
Lack of immutability.
I don't want to get into errors vs exceptions, but I've never heard a pro-errors argument that wasn't hand waving. I think the decision makes sense given Go's genesis (system programming), but given how Go's actually being used, it's a step backwards.
Many of the points you mention are fairly low hanging fruit for inclusion if you are willing to accept the tradeoffs that official Go maintainers are not willing to.
What we have here is people who are already heavily invested in Go to the point where its type system is a real problem for them, yet they do not want to fix the problems, even in light of the relative ease at which at least some the problems can be solved (again, if you are willing to accept the tradeoffs).
You could fork Go and add generics support, but you'd be maintaining that fork forever. The Go core team would never allow it to go back upstream.
The group of people who are able to fork, change and maintain their own Go variant are usually not the people who would ever consider using Go in the first place.
Have a look how long it took PHP to get an AST (instead of the broken mess of reading&executing). Those who are able aren't those who would ever deal with PHP.
I think some of the best parts of Go is the central model: "go get", "go fmt" along with the standard library - if you fork, the burden falls on the fork keep all that stuff working in a sensible way too.
- OCaml is great but parallelism is still limited by its "Global Interpreter Lock" (like Python or Ruby).
- Rust is great but ownership/borrowing is not for everyone and people sometimes prefer relying on a good garbage collector.
- Nim is great but it's a "small" project compared to Go and most people prefer relying on a large ecosystem like the one offered by Go.
- Ada was a major milestone in the history of programming languages, but it's considered by most as an "old" language, compared to Go/Rust/OCaml/Haskell/Scala/etc.
"Although we expected C++ programmers to see Go as an alternative, instead most Go programmers come from languages like Python and Ruby. Very few come from C++"
Maybe Python and Ruby programmers are adopting Go to do system programming, but that isn't my impression.
Any non-trivial Go project will have interface{} sprinkled all over [1], which effectively gives you the guarantees of a dynamic language with the syntactic overhead of a typed language. Truly the worst of both worlds. While I realize it's a tired argument, Go desperately needs generics in some form or another. It would remove most criticism from the language while substantially improving the correctness of programs.
[1] Here's an example with an LRU cache. Just search for interface{} : https://github.com/hashicorp/golang-lru/blob/master/simplelr...
You seem to assume that people who do not like generics complexity will not complain then.
But Go's not my goto language. I'm a staunch believer in the productivity of dynamic languages. In my opinion, Go's less than stellar type system and weak reflection capabilities exasperate this gap, even moreso for most websites / apis (which deal with impedance mismatch at two boundaries).
But, to answer your question. Consider first that Go's very simple to pick up. So the investment is small. Second, where I differ from you is on your second point: Java. I dislike it. It's complicated and verbose and gets in my way. Rust and Go are both proof that we know how to build better languages now. So, when I need to share memory across multiple cores and performance is a concern, I switch to Go because it's fast and simple.