Remix.run Logo
jryio 3 hours ago

I've been saying this for maybe nine months vis-à-vis my consulting work keeps proving it.

Go is an excellent language for LLM code generation. There exists a large stable training corpus, one way to write it, one build system, one formatter, static typing, CSP concurrency that doesn't have C++ footguns.

The language hasn't had a breaking version in over a decade. There's minimal framework churn. When I advise teams to adopt agentic coding workflows at my consultancy [0], Go delivers highly consistent results via Claude and Codex regularly and more often than working with clients using TypeScript and/or Python.

When LLMs have to navigate Python and TypeScript there is a massive combinatorial space of frameworks, typing approaches, and utility libraries.

Too much optionality in the training distribution. The output is high entropy and doesn't converge. Python only dominated early AI coding because ML researchers write Python and trained on Python first. It was path dependence, not merit.\

The thing nobody wants to say is that the reason serious programmers historically hated Go is exactly why LLMs are great at it: There's a ceiling on abstraction.

Go has many many failings (e.g. it took over a decade to get generics). But LLMs don't care about expressiveness, they care about predictability. Go 1.26 just shipped a completely rewritten go fix built on the analysis framework that does AST-level refactoring automatically. That's huge for agentic coding because it keeps codebases modern without needing the latest language features in training data or wasting tokens looking up new signatures.

I spent four years building production public key infrastructure in Golang before LLMs [1]. After working coding agents like everyone else and domain-switching for clients - I've become more of a Go advocate because the language finally delivers on its promise. Engineers have a harder time complaining about the verbose and boilerplate syntax when an LLM does it correctly every single time.

[0]: https://sancho.studio

[1]: https://github.com/zoom/zoom-e2e-whitepaper

gf000 3 hours ago | parent | next [-]

Most of these reasons apply to Java as much, if not more.

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.

hu3 2 hours ago | parent | next [-]

Java has decade(s) of cruft and breaking changes which LLMs were trained on. It's hard to compare. Plus Go compilation speed/test running provides quick iteration for LLMs.

roegerle 2 hours ago | parent [-]

breaking changes? hardly.

nitwit005 an hour ago | parent | next [-]

There is a decently long list of breaking changes now. Removing JavaEE modules from the JDK, and restricting sun.misc.Unsafe, are the ones people usually run into.

gf000 33 minutes ago | parent [-]

These are relatively small-scoped library changes only though.

Meanwhile Go already had a language change, while being less than half its age (loop variable capture).

nitwit005 18 minutes ago | parent [-]

A long enough list of small changes eventually equates to a big change. People generally can't update applications from Java 8 or below to a new one without code updates.

hu3 2 hours ago | parent | prev [-]

Yes, breaking changes. And many ways to do the same thing because the language kept evolving (thankfully).

xannabxlle 2 hours ago | parent | prev | next [-]

Exactly, the propping up of Go seems unfounded. Java in it's newest iterations make it more compelling as a target, and people, especially young people, overlook it because of its stigma as enterprise cruft.

pants2 2 hours ago | parent | prev | next [-]

Certainly not the "one way to write it" idea. Java has a ton of language features.

gf000 2 hours ago | parent [-]

Not really. It has a pretty bare bones OOP (single inheritance, interface), primitives and objects, generics and pretty much that's it.

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).

jimbokun 30 minutes ago | parent [-]

Annotations add a seemingly infinite amount of new semantics. You can’t predict anything with confidence just looking at the code without also studying the annotation processors in depth, which regular Java tools don’t help you with.

EGreg 3 hours ago | parent | prev | next [-]

I wonder what people will say to that.

I personally think neither Go nor Java would be good for "agents". Better to have them sandboxed in WASM.

gf000 2 hours ago | parent | next [-]

Sandboxing is a completely orthogonal issue and WASM is probably not a good direct target for LLMs.

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).

r_lee 2 hours ago | parent | prev [-]

WASM isn't a language you'd want to program with. you can't verify outputs nor is there any proper training data aside from examples and such

yaseer 2 hours ago | parent | prev | next [-]

Except that Go is a simpler, smaller language than Java. That's one of the key points in the post.

gf000 2 hours ago | parent [-]

More simplistic, not really simpler.

JimBlackwood 2 hours ago | parent | prev [-]

I mostly write Go code (and have barely had to write any code myself in the past months), but today I had to do some work in a Java project and Claude Code was a terrible experience.

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.

gf000 an hour ago | parent [-]

Well, there was a Claude outage today, maybe related :D

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.

fasbiner 2 hours ago | parent | prev | next [-]

> I spent four years building production public key infrastructure in Golang before LLMs

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.

slibhb 2 hours ago | parent [-]

LLMs are great with Typescript. But the fact remains that there are many different browsers and several runtimes (Node, Deno, Bun), each of which may have slightly different rules.

CuriouslyC 30 minutes ago | parent | prev | next [-]

This has been studied, Kotlin/C#/Elixir beat it handily.

wiseowise 3 hours ago | parent | prev | next [-]

> Python only dominated early AI coding because ML researchers write Python and trained on Python first. It was path dependence, not merit.

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.

fridder 2 hours ago | parent [-]

It is easy to get started in. Some of the major warts it has, at least the ones that annoy me, revolve around deployment and management. Python packaging has been "fixed" at least 6 times

TrueSlacker0 3 hours ago | parent | prev | next [-]

A lot of those pros apply to c# as well. Which claude and gemeni both do very well with.

bwestergard 2 hours ago | parent [-]

Or Java, for that matter.

treyd 3 hours ago | parent | prev [-]

> But LLMs don't care about expressiveness, they care about predictability.

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.

jimbokun 27 minutes ago | parent | next [-]

Go’s much faster compile times are a big advantage over Rust.

Thaxll 2 hours ago | parent | prev | next [-]

Go is not difficult to maintain at large scale, I mean take Kubernetes for example, it's "trivial" to understand and modified even though it's in the millions loc.

wakawaka28 2 hours ago | parent | prev | next [-]

Rust is unstable and slow to compile. I think these two features make it bad for LLMs and everything else.

maleldil 2 hours ago | parent | next [-]

Why do you say it's unstable?

auxiliarymoose 2 hours ago | parent | next [-]

Take async for example. You have to choose some third-party async runtime which may or may not work with other runtimes, libraries, platforms, etc.

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.

wakawaka28 3 minutes ago | parent | prev [-]

It is literally being changed constantly. They chose to add it to the Linux kernel but they have to build the features they need into the language as they go. It's not backward compatible like C and C++ either. Sure, there are a couple of versions you could try to pin to in Rust, but then all your libraries need to be pinned to the same version (to be fair, this last part is an assumption).

OoooooooO 2 hours ago | parent | prev [-]

Where is Rust unstable?

ForHackernews 3 hours ago | parent | prev [-]

Rust is harder for the bot to get "wrong" in the sense of running-but-does-the-wrong-thing, but it's far less stable than Go and LLMs frequently output Rust that straight up doesn't compile.

gizmo686 2 hours ago | parent | next [-]

LLMs outputting code that doesn't compile is the failure mode you want. Outputting wrong code that compiles is far worse.

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.

zozbot234 2 hours ago | parent | prev [-]

If you use the stable version of Rust, it's stable. There's a very strong commitment from the Rust folks on that specific point.

J_Shelby_J 2 hours ago | parent [-]

The only thing I see is the LLM not being aware of new features, so I have to specify the version rust.