It's an even more popular language with even more training data and also has a better type system so more validation on LLM output, etc.
Meanwhile Go already had a language change, while being less than half its age (loop variable capture).
Newer features fit very nicely and didn't increase the language surface (records are just a normal class with some methods auto-generated, while sealed types are just a restriction on who can subtype an interface -- and yet these give full ADT support for the language that improves readability and type safety).
Java is a fine language, tech stack, and ecosystem, but I agree with the author and parent commenter that this is a sweet spot for Go. Their decision to use it makes a lot of sense.
I personally think neither Go nor Java would be good for "agents". Better to have them sandboxed in WASM.
Of course writing a language that compiles to Wasm is certainly a way, but you would have to sandbox also all the other tools that is used during development (e.g. agents can just call grep/find/etc).
It really felt like using AI tooling of a year or two ago. It wasn’t understanding my prompts, going on tangents, not following the existing style and idioms. Maybe Claude was hungover or doesn’t like mondays, but the contrast with Go was surprising.
One example is that I wanted to add an extra prometheus metric to keep track of an edge case in some for loop. All it had to do was define a counter and increment it. For some reason it would define the counter the line before increment it, instead of defining it next to the other counters outside of the for loop. Technically not wrong (defining a counter is idempotent), but who does that? Especially when the other counters are defined elsewhere in the same function?
Anyway, n=1 but I feel it has an easier time with Go.
My n=1 is that it is pretty good with Java, on par with other popular languages like Python and JS, in line with these 3 probably being a good chunk if not the majority of training data.
Do you think you might perhaps have a bias in the same way that my 9+ years of Typescript usage and advocacy would cause me to have a bias or a material interest?
There is nothing non-trivial you can make that involves the web that is better with Go than Typescript. I look at your personal page and I see that you're already struggling to manage state and css and navigation, or that those things aren't interesting to you.
This tells me you have limited web experience, just as I have limited experience making build scripts at Google and you would probably find my server-side concurrency fairly crude.
Still, you lump Python and Typescript together as "equally frustrating for LLMs" tells me you are not speaking out of direct experience. But the lumping in of Typescript and Python feels really, empirically wrong to me as someone with a foot in both those worlds.
> When LLMs have to navigate Python and TypeScript there is a massive combinatorial space of frameworks, typing approaches, and utility libraries.
I'm right there with you with Python! Lumping in static and dynamic languages is not correct here. Most Python code is from a fragmented ecosystem that took 10+ years to migrate from 2 to 3 and often there is no indication in the corpus even what major version it is and typing caught on very slowly. That's going to be a major problem for a long time, whereas no recent LLM has never ever ever confused .js for .ts or suddenly started writing Node .v12 and angular into a Node 22 and vue project.
I'm happy to throw down the gauntlet if you ever want to have a friendly go vs typescript vibe-code off that spans a reasonably sophisticated full-stack project over three or four hours of live coding.
If you feel like I'm a mean person and attacking you for wanting proof that Typescript is not at parity or superior to Go in terms of LLM legibility, I still would really like you to consider how you can demonstrate your virtuosity and value judgements best.
Python doesn’t need dependence to prove its merit. There’s a reason why it is one the major programming languages and was top 1 for a while.
I think this is true, but it misses a very key point. Go does an impressively bad job at designing APIs that are difficult to misuse, so LLMs will misuse them and will require also writing unit tests to walk through it, just to validate it used the libraries correctly. This isn't always possible (or is awkward/cumbersome) for certain scenarios like database querues.
All of the reasons people argue Go is good for LLMs are more true for Rust. You and the LLM can design libraries to be difficult to misuse, and then get instant feedback from the compiler to the LLM about what it did wrong, and often with suggestions about how it should fix them! This also makes RL deriving from compiler feedback more effective.
This allows the LLMs to reason more abstractly at larger scales, since the abstractions are less leaky (unlike in Go). The ceiling on abstraction screws you here, since troubleshooting requires more deep diving. It's the same reason Go projects become difficult for humans at large scales, too.
With Go, async code written in Go 1.0 compiles and runs the same in Go 1.26, and there is no fragmentation or necessity to reach for third party components.
Setting aside the problems of wrong but compiling code. Wrong and non-compiling code is also much easier to deal with. For training an LLM, you have an objective fitness function to detect compilation errors.
For using an LLM, you can embed the LLM itself in a larger system that checks it's output and either re-rolls on errors, or invokes something to fix the errors.
Python is an interesting one because it's not always obvious the program is wrong or will fail, thanks to dynamic typing.
But another problem is the Python philosophy since 3.0. Where once backwards compatibility was treated as almost sacrosanct, 3.0+ does not. 2.7 persisted for so long for this reason. But minor releases in 3.x make breaking changes and it's wild to me.
I just wish Go had cooperative async/await rather than channels because (IMHO) cooperative async/await is a vastly superior abstraction to unbuffered channels in particular.