- testing
- benchmark
- profiling
- cross compilation ( that work from any platform, like compiling a windows .exe from your raspberry pi for example )
- some linting
- documentation
- package mgmt
- bug report
- code generation
- etc...
Java is probably more advanced in some fields ( like tracing / profiling ) but it lacks others.
Coming from ts, tooling like tsconfig has a lot of options, but sensible defaults can be set with a single flag like strict mode. If some org has some specialized needs, they can dive into the configuration and get what they need.
With golang, not only would it be a lot for any single team to offer all those features at a decent level of polish, the golang culture in particular is very, very resistant to small bits of comfort because of dogma like "worse is better". It's kind of similar to Haskell's "avoid success at all cost".
Also there’s a lot of go tooling that doesn’t come from go team itself because go standard library exposes first class code introspection utilities. go vet is an example of this
The commonJS/module transition is a nightmare. The fact that something like 'prisma' exists - a c-written 'query engine' that turns prisma js into sql.. wut?
This ecosystem is on a highway to hell literally.. I really hope Bun works out, because I do like Typescript, I do like programming in it - but I'm absolutely done with spending hours upon hours figuring out configs in tsconfig, jest, package.json eslintrc, prettier, vstest and whatever the next 'new' abstraction is. In Go I can just focus on the code and forget about the rest
You shouldn't need anything (except strict mode) in a new TS project.
That said, TS is quickly becoming the antithesis of what Go tries; every release for the past few years I've seen now are all features where I'm like, "I will never need or use this". Some conveniences have been improved on - like better type inference - but that will mainly allow for cleaning up workarounds.
"some orgs with specialised needs" are going to be legacy projects, either older TS versions that didn't have the features that it does now, or JS codebases. This isn't generally an issue with Go projects, most of which are greenfield. That said, there's some X to Go conversion projects that produce less than ideal code though, like usage of the `interface{}` type that at this point is a code smell.
The only thing one could arguably argue that Go does better is value types, but even that requires careful coding so that escape analysis is triggered, and in that sense, it is only a matter to use a JVM implementation like GraalVM, OpenJ9, Android ART, PTC, Aicas, Azul.
> cross compilation ( that work from any platform, like compiling a windows .exe from your raspberry pi for example )
This, I think is one of Go's best selling point.
For years until 1.19 the Go GC has had only one tuning parameter (GOGC).
You really, truly, just run.
As for Go, good luck doing just run when a code repo breaks all those URL hardcoded in source code.
* the go module proxy ensures repos are never deleted, so everything continues to work
* changing to a new dep is as easy as either a replace directive or just find and replace the old url
If a module author deletes or relocates their module, the old module is not deleted or renamed from the module proxy. It is kept around forever. Code that depends on it to not break does not break.
If they relocated and you want to update to the new location, perhaps for bug fixes, then you do have to do a bit extra work (a find and replace, or a module level replace directive) but it’s a rare event and generally a minor effort, in my opinion, so I don’t think this is a significant flaw.
For most users most of the time they don’t need to think about this at all.
You're on a tear in this thread being wrong about how Go works, but I'm really curious what extremely specific series of events you're imagining would have to happen to lead to this outcome. If I use a dependency, it gets saved in the module proxy, I can also vendor it. You would have to, as a maintainer, deliberately try to screw over anybody using your library to accomplish what you describe.
Being a mantainer has nothing to do with some kind of gentlemens code of condut.
Additionally, of course it would be nice to have more GC options, such as choosing between a throughput-oriented GC design and a latency-oriented one, having the option of a compacting GC of some kind to avoid fragmentation, or even having a real time GC option.
Go has chosen a very old-fashioned GC design with very few tuning parameters possible, but even so it only exposes a very basic form of control.
This sounds like something you would hear 10 years ago in relation to the CMS garbage collector. Since Java 9, G1 has been the default gc for multi core workloads and is self-tuning. The CMS gc was removed 4 years ago. If you do need to tune G1, the primary knob is target pause time. While other knobs exist, you should think carefully before using them.
We run all of our workloads with vanilla settings.
Also, the OpenJDK JVM supports live debugging and code hotswap, going so far as to de-optimize code you're debugging on the fly to make it readable. Go doesn't support live code reload even in local builds.
The current format has very limited tooling; "go tool" has some extremely rudimentary visualization. There is gotraceui [1], which is much better, though you need to use Go trace regions to get much useful context.
There's a proposal to support Perfetto [2], but I don't know if anything has come of it.