> So with this, the last thing Go had going for it over Java is gone, right?
Go still has composition over inheritance, which is vastly more flexible. Go favors explicit (verbose copy-paste, redundancy, use stdlib first, libraries second) over implicit (magic annotations, frameworks everywhere) and I like when I can understand what's happening without holding 10 files in my brain context. Go's memory usage doesn't trigger the OOM killer every 10 minutes. Go favors copy-pasting because what you copy is short and understandable, and function names don't have 10 words in it.
It's always going to be a personal choice, and even though virtual threads bring java closer to where go is, it's still not there for me.
It's not so much part of the language but it's an idiom that is said by one of its authors (https://youtube.com/watch?v=PAAkCSZUG1c&t=9m28s). "Code reuse" always has some non-compressible context: another import with a line in go.mod, another repo and dependency, which doc is going to be on another page/site, etc... It makes sense for big dependencies but not for small ones; the threshold where "small" becomes "big" being of course subjective.
Go still has composition over inheritance, which is vastly more flexible. Go favors explicit (verbose copy-paste, redundancy, use stdlib first, libraries second) over implicit (magic annotations, frameworks everywhere) and I like when I can understand what's happening without holding 10 files in my brain context. Go's memory usage doesn't trigger the OOM killer every 10 minutes. Go favors copy-pasting because what you copy is short and understandable, and function names don't have 10 words in it.
It's always going to be a personal choice, and even though virtual threads bring java closer to where go is, it's still not there for me.