upvote
Uber reported that their Go code has quantitatively more concurrency bugs than code in other languages, and while to me it seems obvious from looking at Go's concurrency model, this is backed by actual data. Is there any quantitative data to back the claim that Go is better in an LLM based workflow than another popular language?
reply
Matches my experience as well. Go fans have conflated "can easily make something concurrent" with "does concurrency well." Go's primitives for concurrency should almost never be used directly and Engineers below a certain skill level shouldn't be allowed to use them directly ever for long running production code.

As another example, Go still has not yielded a correct implementation of Raft or Paxos while there are dozens in Java, C++, and Rust. Antithesis found some more bugs in HashiCorp's Raft implementation recently[0]. I'm sure etcd still has some kicking around.

Maybe this is a "don't throw the baby out with the bath water' problem but the general evolution of Go has been lackluster. I reach for Rust, Zig, and modern Java instead depending on the specific needs and constraints.

0 - https://antithesis.com/blog/2026/finding-bugs-in-raft-implem...

reply
The "world" runs on Kubernetes which is using Raft: https://pkg.go.dev/go.etcd.io/etcd/raft/v3

Are you saying that this implementation is wrong?

"This Raft library is stable and feature complete. As of 2016, it is the most widely used Raft library in production, serving tens of thousands clusters each day. It powers distributed systems such as etcd, Kubernetes, Docker Swarm, Cloud Foundry Diego, CockroachDB, TiDB, Project Calico, Flannel, Hyperledger and more."

One of the most popular distributed DB is Cockroach which is written in go and also uses Raft: https://github.com/cockroachdb/cockroach/tree/master/pkg/raf...

reply
etcd has had numerous liveness and safety bugs, with one happening as recently as December of 2025. Would you consider that a correct implementation?

You may be interested in knowing that the largest managed Kubernetes service in the world (AWS EKS) ripped out etcd for in favor of their homegrown consensus service for large scale EKS clusters: https://aws.amazon.com/blogs/containers/under-the-hood-amazo...

reply
etcd is some of the most amateur code I've ever seen, despite being one of the oldest and presumably most mature "infrastructure" projects written in Go.

goBGP is arguably even worse.

I don't have a third place in mind that's even worth mentioning relative to these two.

reply
just curious, what problems do you see with gobgp?

(I have only a rather basic familiarity with go, but was considering gobgp for an infra project...)

reply
Not speaking to their code, but to start GoBGP has the worst performance of any BGP daemon by a large margin [1].

[1] https://elegantnetwork.github.io/posts/comparing-open-source...

reply
Garbage collected languages like Go will always have worse performance than lower level languages like C (frr and bird are implemented in C).

Gobgp is great if you want to embed it directly into a Go app though. Talos Linux has done that recently.

reply
No they won't. They are generally faster in throughput than any non-gc application that isn't heavily hand optimized. Their problems are higher memory usage and unpredictable latency, not speed.
reply
Sorry to pile on, but yeah, I wanted to use etcd during 2021 and 2022, around v3.5, but etcd had serious issues including silent data corruption. If you are curious, ask gemini flash "there were a number of etcd releases years ago where it seems a new wave of developers came in and started breaking everything"
reply
I'd like to know what you base your statement on that the Raft implementations in etcd or CockroachDB are incorrect. Your original paper does not mention those implementations, so where does that claim come from?
reply
Having run a fleet of 100s of etcd clusters for 10000s of rps, and the fact that upstream runs tests similar to antithesis and recently partnered with antithesis [0], and jepsen has tested it long ago as well [1]. Etcd's raft algorithm is fine. Someone even did a TLA+ proof on it in the last couple years[2]. Yes there was a correctness issue a few years ago but otherwise the person you're replying to doesn't know what they're talking about. Also those bugs have nothing to do with the raft implementation, but instead the state machine implemented on top.

0: https://etcd.io/blog/2025/autonomus_testing_with_antithesis/

1: https://jepsen.io/analyses/etcd-3.4.3

2: https://github.com/etcd-io/raft/pull/113

reply
doesnt raft have a problem that it assumes no hysteresis? and that in general you can construct a latency graph that deterministically causes a permanent lock in the leadership election phase?
reply
Is the correctness of its implementation of the algorithm unaffected by bugs in this state machine? Maybe I missed something.
reply
The raft algorithm works and if you implemented a less complex state machine (like using a simpler kv store that doesn't need global event ordering via revisions and watches) it would work. That's what antithesis said they did to test the raft algorithms in the other article linked
reply
"there was a correction issue" is downplaying it. Etcd is truly the worst example of Raft.

Etcd corruption and loss of quorum is extremely common in practice and the GitHub issues sit for years. The design is simple, the performance is modest, yet it still has still never been reliable, despite being marketed as so. I can't speak to whether this is specifically due to their Raft implementation, but I'd argue the entire codebase is over-engineered and questionable.

reply
My beef with etcd is that its neither performant nor reliable.

Its very much {reliable, performant, flexible} pick none.

reply
Their lock, leader election, sessions, and leases are all awful and I'd never recommend anyone to use those. But as a strongly consistent kv store and if you need the watch mechanics, its useful. It has its place and that's mostly being used by kubernetes.
reply
Surely the King is doing it, so that must be the correct way. Look, the King even wears clothes and is totally not naked at all.

That the world runs on Kubernetes is no qualitative statement about the correctness of its Raft implementation. You can say that it's clearly good enough to not matter most of the time, but that is a different statement. No matter who you look at, they're just cooking with gas like you do, and they can make mistakes in just the same way.

Now; I'm only attacking your argument. I do neither know nor particularly care about the correctness of that implementation itself. There's been better refutations of the claim you replied to in other answers anyway.

reply
It's not even a qualitative statement about Kubernetes.
reply
Kubernetes doesn't solve any technical problem, so the language it's written in is irrelevant.
reply
I have a bunch of volumes that I'd like to get automatically attached and mounted to nodes on which their respective workload runs (which are automatically scheduled) who automatically fetch and mount their config files and secrets from a HA DB on demand. I also need some internal loadbalancing and integrations with something like certbot for all of my web workloads. Id also like to make sure that I get metrics and logs from every workload in some form.

Thats basically it for starters, what non-technical solution do you propose?

reply
If k8s works for you, then go for it.

But k8s was invented so that "dev" and "ops" teams could play nicely when they are different org structures, with their own budgets, deadlines, etc.

If it solves some technical issue then that's incidental.

reply
What I meant is that the fact that the world is running on Kubernetes is not a qualitative statement about Kubernetes.
reply
etcd is notoriously unreliable and one of the biggest problems in k8s.

I didn't know Go just isn't a good language for it, but now that I know I'm no longer surprised at etcd being problematic.

reply
I'm running big k8s cluster and my small ones at home for 8 years, never had an etcd issue.

Could you elaborate?

reply
Having maintained multiple etcd clusters for self-managed kubernetes the last few years I disagree with the "problematic" characterization.

Sure it may not be the best fit in a scenario where you want a cluster spanned over the entire globe (thats why GKE uses paxos-based Spanner instead of it) , but even spanned across an entire continent (in europe via glass fiber) it works quite well for me. Its one of the least problematic parts of the stack.

reply
That's not remotely what he's saying at all.
reply
> As another example, Go still has not yielded a correct implementation of Raft or Paxos

> are you saying this implementation is wrong?

> That's not remotely what he's saying at all.

I'm v confused by this thread

reply
I don't care for Go myself (especially its concurrency model, which is a total dinosaur in a world where we have structured concurrency) so I'm not saying this to support my favourite language, but:

That is literally what the comment says.

reply
Thank you. I don't know why this is so complicated.
reply
> Go is bad so "I reach for Rust, Zig..."

I hope my every competitor will take your advice to heart, as one of our competitors did when they read that "Go is not a memory safe language", so they wrote a blog about how they are porting to Rust. While our team was moving fast and using those "primitives that should almost never be used" around our long running production code base with success.

Some time has passed and now their company does not exist anymore and we have a lot of their clients.

Thank you!

reply
Perhaps that company failed because it chose to port things to Rust and not because of Rust itself? Or any other number of reasons that survivorship bias might be mistaking.
reply
deleted
reply
Where would one ever read that Go is not memory safe? That's just a false claim, and anyone believing it would have probably gone out of business regardless of choice of programming language.
reply
Nobody serious claims Go is fully memory safe. Here's Russ Cox telling you concurrency is a hole in the memory safety: https://research.swtch.com/gorace
reply
It looks like Go is memory safe for single threads and channels, but not for shared memory between threads: https://en.wikipedia.org/wiki/Go_(programming_language)#Lack...

> Go's internal data structures like interface values, slice headers, hash tables, and string headers are not immune to data races, so type and memory safety can be violated in multithreaded programs that modify shared instances of those types without synchronization.[113][114]

reply
By a strict definition of memory safety it isn't - you can tear two-pointer-wide values using data races and cause arbitrary memory issues if you try to using only normal code.

It's close enough for most purposes... but it isn't.

reply
My ex-boss was a JS guy and then moved over to Rust. He loathed Go because it has pointers and it's possible to use a nil pointer if you are not competent.

JS is fine for what and where it is, Rust is fine too. I just appreciate the stupid simple nature of Go and it does the job just fine.

reply
What domain is your company in?
reply
You seem to be implying, based on the rest of the thread, that Go has some sort of special defect that keeps it from implementing Raft correctly. But the "special defect" that Go has is that it in practice implements the same primitives in practice that almost every other mainstream language does, rather than implementing some sort of super-safe concurrency primitive like Erlang or Pony, or being immutable like Haskell. And even those things are of only marginal utility for Raft, preventing some local issues, but the hard part of Raft is more in the logic and the communication, for which none of these languages have any sort of special support or anything that will particularly help you get it right. Of the languages you listed only Rust provides any assistence over the standard mainstream languages, and like I said, in the context of Raft, it is not necessarily all that helpful.

If you want to see something that could potentially impact Raft's correctness, search the last couple of days of the HN front page for choreographic languages [1]. But none of these are even remotely mainstream enough to depend on for anything. Nor do I know if anyone in these languages has implemented Raft. A rather good test case for them, if any of them are looking. That's something that could actually help a Raft implementation's correctness, not just fiddle around the edges of local concurrency issues.

[1]: https://hn.algolia.com/?dateRange=all&page=0&prefix=true&que...

reply
Also, wasn’t this about concurrency? You could, if you really wanted, write a paxos or raft implementation with no concurrency.
reply
That does not seem like a fair/accurate reference?

The antithesis author states:

  "we’ve found bugs in every Raft implementation we’ve tested, including HashiCorp Raft, Aeron Cluster, OpenRaft, and MicroRaft"
reply
You're misreading what I said. I didn't say other languages don't have buggy Raft/Paxos implementations, just that Go is yet to yield a single correct one.
reply
I think you're projecting. You wrote

> Go still has not yielded a correct implementation of Raft or Paxos while there are dozens in Java, C++, and Rust.

That says that there are correct (i.e., bug-free) implementations in those languages. The GP noted

> "we’ve found bugs in every Raft implementation we’ve tested, ..."

which says that there aren't any correct ones. You then wrote

> I didn't say other languages don't have buggy Raft/Paxos implementations

which is a strawman. The issue is whether there are correct implementations. That there are buggy ones is irrelevant.

(FWIW I have no dog in this fight ... I'm just reading here.)

reply
> The GP noted

>> "we’ve found bugs in every Raft implementation we’ve tested, ..."

> which says that there aren't any correct ones

That only follows if the GP tested every Raft implementation in existence and no new ones were written since.

reply
The intersection of the set of Raft libraries Antithesis tested and all Raft libraries in existence do not fully overlap. I personally have worked on multiple proprietary ones that Antithesis would not have access to.
reply
I work at Antithesis, we're happy to test out any Raft implementation that has so far escaped our notice :)
reply
I love what you all do! I don’t have any to submit. Enough time with consensus teaches you to avoid it unless it’s really, truly needed.
reply
Lol "I swear have a girlfriend, she just goes to a different school"
reply
Even if so, the "You're misreading what I said" charge was bogus and it would be nice if you admitted that.

Edit:

> What are they implying by citing that? That Raft implementations in all languages have bugs?

That's what it says.

> I've already pointed out that is false.

You claimed that, and it's being disputed.

> Please let me know, since you're so comfortable speaking for them.

This has veered into bad faith ... I won't comment further.

reply
Further, they can still edit their comment to correct it, but opting not to.
reply
But they are misreading what I said. My original post is clearly about Go. What they wrote is also ambiguous.

> The antithesis author states:

> "we’ve found bugs in every Raft implementation we’ve tested, including HashiCorp Raft, Aeron Cluster, OpenRaft, and MicroRaft"

What are they implying by citing that? That every language has a Raft implementation with bugs? Yes that's probably accurate because lots of people make Raft implementations for fun and learning. Again, Go does not have a single Raft/Paxos implementation that is rock solid. I have seen many in C++, Java, and Rust that are doing tens of millions of requests per second in production for over a decade.

Is their point that Go is not the only language with this problem? My post already points out the track record is that Go is the problem for writing correct code in highly critical domains.

reply
If we rely on their evidence alone, it suggests nobody has ever made a correct implementation, so we learn nothing about Go. "Go has yet to yield a correct one" is an extremely misleading way to present evidence that says the same thing about every language.

The only way this becomes useful for comparing languages is if somebody gives evidence of correct implementations in other languages. You're claiming they exist but with no evidence and suggesting they're secret. How do you know those don't have bugs? Did any concurrency bug experts do extensive testing on them? And can we disprove secret Go implementations of the same quality?

reply
You're being very mealy-mouthed, even here, it reads as "The pre-eminent Go implementation can't even get it right" and yet the implementations Antithesis tested in Rust are apparently people's random "fun and learning" projects, nothing serious, and certainly not all the proprietary implementations that you've used that are all correct.
reply
Also, it simply isn't true that @ramoz misread what they wrote, as I pointed out in both of my comments.
reply
> That every language has a Raft implementation with bugs? Yes that's probably accurate because lots of people make Raft implementations for fun and learning. Again, Go does not have a single Raft/Paxos implementation that is rock solid. I have seen many in C++, Java, and Rust that are doing tens of millions of requests per second in production for over a decade.

No, they are citing that every Raft implementation that Antithesis has tested has bugs. The etcd implementation you note in go that has bugs also does tens of millions of QPS and is over a decade old. How are you confident that the proprietary implementations that presumably haven't been fully tested don't have subtle bugs that don't show up in practice?

reply
To combine both TFA with this comment: I find that LLMs are ~fine at generating/editing gocode, or at least as ~fine as they generate most mainstream languages.

But good god, the second it gets to anything concurrency-related, it just loses its mind. As much as it's gotten vaguely ok to try to let the agents loose on some bits of the codebase, they simply can't even do table stakes stuff with the kinds of concurrency you see in real life.

reply
Correct concurrent code is mind-bogglingly hard even for seasoned veteran humans (and don't get me started on distributed programming...), so it's hardly surprising that LLMs with their limited context windows into the code have a hard time writing correct concurrent code
reply
My experience as well. LLMs also struggle with Rust's many abstractions and offerings but you can know that if it compiles it is data race free and work with the LLM to use better abstractions over time.

Zig is also good at this but requires more up front design (thread-per-core, static allocation, etc.) and consistent checks to verify rules are followed.

reply
C/C++ has "compiles but may have undefined behavior". Golang has numerous "compiles but has incorrect behavior" (normally known as footguns). Meanwhile with Rust, if you get past the compilation step, bugs become much much fewer. (You can still have memory leaks, but those are easily traceable).

It seems like claude code can code Rust pretty well with Opus, and I've started moving codebases away from Golang to Rust at work with Opus. Spin up an LLM and it cranks on it for a while, and as a benefit, I get easy apis to build on with other languages.

And that's the problem with Golang really, not that it's a bad language per se (all languages have footguns), but that the language interoperability story is terrible. Meanwhile Rust and Python/C/C++ go great together like peanut butter and chocolate. And I love it.

reply
> You can still have memory leaks

And deadlocks. "Fearless concurrency" helps a lot, but logic bugs are still possible.

reply
I wouldn't be surprised if Java has a much better experience here. After all, java.util.concurrent has many great implementations, and Java's `record`s are immutable, as are it's upcoming value types.
reply
I was thinking same but C#.
reply
Java has so many excellent concurrency containers, plus robust 3rd-party containers like JCTools. It puzzles me why Go communities do not offer such containers.
reply
No thread/goroutine handles for fork/join handling from "outside", and no generics for many formative years that influenced tons of habits, then significantly weaker generics (improving very soon[1]), have all led to most concurrent code to be very "intrusive" - you create bare threads and add bare synchronization primitives (or nearly) by hand inside the threaded code to make it concurrent. `errgroup` is as far as a lot of code goes, in terms of sophistication.

Java leans heavily in the other direction: a lot of concurrency is added externally, without changing existing code, often in very declarative-flavored ways.

E.g. Future<T> serves as a foundation for a ridiculous amount of stuff, while Go forces channels for `select` whether they model your problem nicely or not, and they're very difficult (often impossible) to wrap without changing semantics.

There are very obviously lots of counter-examples for both langs (`synchronized`, rill in Go, etc), and I expect Go to become more Java-flavored in time (it already has moved this direction somewhat, and 1.27 will enable a lot more). But I think it's a fair summary of broad ecosystem habits.

1: https://tip.golang.org/doc/go1.27 (not yet released)

reply
> Go still has not yielded a correct implementation of Raft or Paxos while there are dozens in Java, C++, and Rust. Antithesis found some more bugs in HashiCorp's Raft implementation recently[0].

the source you link to contradicts your own claims.

they say:

> we’ve found bugs in every Raft implementation we’ve tested, including HashiCorp Raft, Aeron Cluster, OpenRaft, and MicroRaft

(besides Go, that's 2 in Java and 1 in Rust)

reply
The Raft bugs are the wrong kind of concurrency --- they're distsys bugs, not multithreading bugs. Not a good example, and a little telling that you'd cite it.
reply
Yeah, but AI is better at debugging than people are, so what's the issue?
reply
What primitives are we discussing? Any Go programmer can and should use the `go` keyword and the `sync.Mutex` type from their first program.
reply
It's pretty easy to get yourself into trouble with channels: deadlocks, send on closed, channel leaks, deadlocks "fixed" thoughtlessly with arbitrarily-sized buffers, etc.
reply
This seems to have little to do with Go's facilities. Any concurrent program has hazards like these.
reply
In my experience, shared memory instills the appropriate fear and caution, while the apparent simplicity of channels encourages novice Go programers to take on concurrency projects beyond their abilities and without due care. Been on both the submitter and reviewer side of that plenty of times in 10 years.
reply
Rust's concurrency libraries leverage the type system to make these issues much harder to encounter.
reply
You know there’s no quantitative data. It’s vibes from the top down.
reply
Which languages are they comparing with? From what I understood, Rust makes stronger correctness guarantees, including with regard to concurrency, but has a much higher learning curve and cognitive load.
reply
Link to the uber report? Could not find it (unless it is this: https://www.uber.com/us/en/blog/data-race-patterns-in-go/)
reply
This is the actual link to the academic paper (https://arxiv.org/pdf/2204.00764)
reply
Just reading the abstract, it talks about finding a number of bugs (across millions of lines of code) but I didn't see any claims that there would be fewer bugs in a different language.

Go obviously does not stop you from writing buggy code. Neither does rust or zig or whatever. Does go make it more likely to have bugs? Or a specific class of bug? Like, the real world is about trade offs.

reply
Uber has fairly large golang and java codebases so they have more of an apple to apples comparison here since they are both GC languages of a similar performance class. And if a large population tends to make more mistakes with 200hp sedan A vs 200hp sedan B, there is probably something up with the design of sedan A.
reply
I agree, but does that study claim there are more errors per line/function/whatever in golang than java?
reply
That article is meh. All of those issues are either addressed or junior programmer mistakes.

Yes, it's a bit of blame the user which will likely get the retort of "but I thought Go was perfect for junior engineers?"

Yes, there are footguns but none of the points therein were compelling.

reply
They never said that.
reply
The best way to write concurrency in any language is a single threaded polling loop. Goroutines and messages are just as bad as all the other alternatives, which is to say they are a miserable way to write code.

But Go is also perfectly good at single threaded polling loops.

reply
Trust me bro
reply
Uber has a history of blaming the tool - in Facebook fashion - rather than admitting their “talent” sucks and they didn’t hire on merit.

They used to blame Python a lot too - Python is slow compared to others but not so slow to matter that much, and you can build other services around it to handle certain work.

Facebook - who chose PHP - used to blame iOS/Obj-c as the reason they couldn’t build a decent Facebook native app in the early days (anyone remember Fastbook?)

I would take it with a grain of salt.

reply
What concrete arguments are there to believe in your talent hypothesis instead of their tool hypothesis?

A couple more comments like this from you, and I'll be able to say, "cyanmoonx has a history of blaming the talent rather than bad tools". There being a history like that is neither an argument for nor against tools being bad. And also, don't forget that bad tools and bad talent don't rule each other out.

reply
yup, show receipts
reply
We've seen a pretty consistent pattern in our evaluations where Go is among the languages that models perform worst with (alongside Python), for reasons unclear. Our coding evaluations are typically measuring the foresight and planning expressed in code that is run in interactive environments/games.

This trend has been there since we started evaluating models using different languages in February 2026 and if anything, the disparity has grown in frontier models. Even Google models prefer Kotlin/C#/Rust for coming up with creative ideas (compilation success is a different story). Data at https://gertlabs.com/rankings

That being said, models love to recommend Go, and Go does have a lot going for it, especially if you are serving a public-facing website. So most of our public facing API handlers are written in Go, and we offload some of our most important binaries to Rust. There are just too many reasons not to use the languages that models think a little more effectively in.

reply
I work at a large devsec company which uses primarily Go and TypeScript

I've found that the LLM generated Go has few mistakes, and generally isn't too obscure. But the volume of code is so high, colleagues do a bad job of reviewing it.

I've seen a lot of very silly decisions made, like returning the wrong HTTP code, or miscategorizing a metric used for an SLO, that I just don't think is helped by the sheer volume of code one has to wade through.

Ironically, we are considering migrating some initiatives to Rust, exactly because experiments indicate it works well with LLM development.

reply
Isn't any equivalent system going to have more statements in Rust than it would have in Go?
reply
Yes, and that's the case I've seen as well. I would also say rust is also more heavy on symbols, which can make code look kinda hard to parse in places.

But weirdly Opus (N=1) in Claude Code does okay on it. Enough I can reliably have it write software and feel confident it works.

reply
Why would you think so? Rust provide better type system and abstraction mechanisms compared to Go, hence equivalent system should have less lines of code, at least in from my experience.
reply
Considering every other line of Go is `if err != nil`, this makes sense. I do prefer Go's simplicity, personally.
reply
> For a language team, Go is a dream.

I agree very strongly. There's no debate about things that have 1000000 permutations in other languages. e.g. The correct format can always be checked by `go fmt` with no real config options. the end.

reply
I mean this isn't true, formatting is the most trivial part. And so many languages have an opinionated formatter these days (e.g. Black)
reply
>> ...there is no debate...

> ...And so many languages have an opinionated formatter these days

The crux of gp's post is for Go, there is no debate as 'go fmt' is the only one that matters. Black is great, but some people prefer Ruff, leading to ...debates about which formatter the team/org should use. Go's batteries-included philosophy makes those discussions moot on so many levels beyond formatting.

reply
As if projects haven't used to have a coding style. What's so hard in saying that code should be formatted with Black, yapf, ruff etc, beats me.
reply
Literally within this thread someone has already suggested using ruff instead of Black and nobody here are colleagues.
reply
It's a silly argument and the lowest form of bike-shedding on the level of tabs vs commas. People with no other substantive contributions use formatting as a beard.

The first one to choose it (whatever it happens to be) wins and that's the end of it. If it isn't the end of it you've got a talent issue.

reply
> It's a silly argument and the lowest form of bike-shedding on the level of tabs vs commas

Guess what other low-level bike-shedding argument 'go fmt' obviates? That's right - tabs vs spaces!

> If it isn't the end of it you've got a talent issue.

I know you meant this as a slur, but the implication is Go works better than other languages for those who have what you call "a talent issue"

reply
Bad example. Ruff's formatter has the same style as Black. It's documented as a "drop-in replacement". The difference is mostly performance.

In any case, that's a single decision the project lead takes once.

reply
what is "Black"? (For hopefully obvious reasons, I couldn't find results with google, lol)
reply
What did you search?

If I do the simplest possible thing that isn't a single word, by highlighting "opinionated formatter these days (e.g. Black)" and clicking search, I get the right result. I also get the right result for black formatter, and I get the right result if I yolo the entire comment as my search.

reply
reply
But you're probably better off with Ruff these days: https://docs.astral.sh/ruff/

Similar to black but faster, written in Rust, by the same team who created uv.

reply
So... A: not trivial. And B: not part of the language.

> mean this isn't true, formatting is the most trivial part. And so many languages have an opinionated formatter these days (e.g. Black)

I don't think this is correct

reply
This back-and-forth is a good example of why Go benefits from having a centralized linter. And uv isn't the official Python package manager even though it should be.
reply
I don't get why this is a big issue. This isn't some recurrent decision to be made. It's something a lead decides once and the project follows. That's it. Many companies have style guides anyway (eg Google[1]); the choice of a formatter is much simpler.

[1] https://google.github.io/styleguide/go/

reply
Because at some point you have to interact with some other team or project that made a different decision. And whatever you picked might fall out of favor and lose support. There's already a graveyard of Python type linters, including Google's pytype.

Especially the uv thing. You clone some non-uv git repo that has no pyproject.toml and you don't know what to install. Maybe has requirements.txt but it's partially wrong.

reply
[dead]
reply
I want to ignore Naysayers in the thread but even SOTA LLMs write boilerplate like it is Go 1.14. I have to constantly nudge it to use newer language features properly, even if it's also in my rules/ CLAUDE md files.
reply
Your post reminds me of what I love about Python, we have PEP-8 which is a style guide, and it kind of shifts how you write code a bit (for the better) which is something I sorely miss in other languages, I don't get the feeling people care about style guides for other languages very much.
reply
If you know any other language, you basically already know Go (with the exception of the channels stuff). The biggest pain is the if err != nil stuff, which I know some people like but it is suboptimal in my view. While far better than C# and Java's exceptions, far worse than Zig's model.
reply

    > far better than C# and Java's exceptions
What is wrong with them? When writing enterprise CRUD apps, they are very useful.
reply
People don't understand exceptional control flow. They think they have to catch them at every point, instead of using them as intended (having a central boundary of error handling where you have enough context whether to retry or abort the operation). So they think Go errors are better.

With exceptions you can

1. Set exception breakpoints.

2. Have real stack traces.

3. No need to write 3 lines of boiler plate every 1 line of code which interacts with outside world.

Ironically this is the case in Go's niche - devopshit, cloud webshit - where the boilerplate error handling makes even less sense since because

1. You are making a network call or OS interactions every 2 lines which can err

2. The consequences of an unhandled exception are actually quite less severe. At worst your request will 500 or the application will restart - which is a consideration you can't escape in these environments.

3. I have seen indiscriminate error handling written by substandard developers which simply concatenates the full wrapped error string to API, leaking full details. At least with exceptions, you can designate different types of exception for 404s vs ayth errors vs bad requests vs Internal errors, and have a central handler which filters out. In go theoretically you can do this, but I have never seen someone utilize errors.As over stringy error handling.

I like Go - it has nice stdlib, nice compiler and runtime, and actually dared to innovate away from the fat-ass LLVM monoculture and made green threads popular. But error handling and uninitialised values sticks out like a sore thumb. It's impossible to read code which does many API/network/OS interactions.

reply
Yeah, panic/defer/recover are so much better. /s
reply
Yep. Have a primarily Go backend and from even early on the agents were doing a good job.

Now they are even better than me.

I do think the way software is organized for primarily agent driven repos will need to change a bit from how I preferred setting things up. (Guessing we're going to be returning to a world of microservices in the near future.)

reply
Go wins for simplicity. however what I have seen is companies end up going with Java coz it's simple enough - not simple as Go, but simple enough + fast enough.

though the letdown with Java is the wider ecosystem that makes unwarranted contraptions out of simple things.

reply
Go's big advantage was M:N threads. Java's biggest flaw has been the lack of cooperative multitasking, which people worked around by mangling their code with promises. Now Java has M:N threads too thanks to Project Loom, but there's so much code written before that will never really go away.
reply
Java already had M:N threads in the early days, aka green threads, because the JVM and Java specifications did not assert what kind of threading was to be provided.

Thus most JVM implementations had a mix of red (1:1:) and green (M:N) threads, eventually only red threads were kept in the surviving implementations.

With Project Loom now both models are officially supported and part of the specification.

reply
Yeah I've heard of the Java 1-2 greenthreads, but supposedly those were M:1, ie you could only run them on one core. At least this SCO release note linked from Wikipedia says that: https://www.sco.com/developers/java/j2sdk122-001/ReleaseNote... And the pros are more about compatibility than performance
reply
How have you found a SCO note, which never did nothing relevant for Java?

Here from Oracle, as historically taken from Sun documentation for JDK 1.1.

=> Many-to-Many Model (Java on Solaris--Native Threads)

https://docs.oracle.com/cd/E19455-01/806-3461/6jck06gqk/inde...

reply
I think there's a naming confusion here. You said "M:N threads, aka green threads". However, your linked document clarifies that "green threads" are the M:1 threads that "[do] not exploit multiprocessors" (see the "Green Threads" parenthetical in the first subheading). It is interesting that JDK 1.1 also had an M:N threading model, but that's not what people usually mean by green threads.
reply
I always understood it like that, however maybe it is on me, when reading this with more detail.
reply
Go is heavily opinionated on style, design, and semantics. Its design was around being as concise as possible…which means token efficient.

Yeah Go is my preferred language to code with AI. Second up is type script. Followed by Java, then Python.

reply
Go design is not around being concise as possible, in fact it's the complete opposite.

One of the cores behind Go is to make language simple, even if at the expense of more verbose code.

Two main examples of this is the infamous 'if err != nil' and how you handle filter/map/funcional operations.

reply
Yes but it’s err not error. The variable and method names are meant to be concise and highly readable without the CS fluff of Java naming hell.
reply
I don't think naming convention is the kind of stuff that helps save tokens, specially considering how text is tokenized.

On the other hand, being able to write 'list.filter(v => v.selected)' (or something similar) instead of:

  listFiltered := []Item{}
  for _, item := range list {
    if item.selected {
      listFiltered = append(listFiltered, item)
    }
  }
would save much more tokens.
reply
You can have that with generic functions, although Go's lambda syntax is too verbose. The slices package has DeleteFunc, which is kind of the opposite. I don't know why they have Filter.

https://pkg.go.dev/slices#DeleteFunc

reply
Isn't Netflix a Java shop
reply
They use more than just Java. The UI was originally C#... I'm still surprised the front-end was C# but they went with Java longer term for the backend.
reply
When I worked at OpenConnect (Netflix's CDN) there was a lot of Python too, and I started porting a lot of the tooling to Go. By the time I left (2019), Go was really starting to take off outside of OpenConnect too -- but yes, there's historically a huge amount of Java there.
reply
Likely because Netflix relied on Silverlight for video playback early on. I'd be surprised if they still had C# in their front-end stack (and I say that as a general C# fan, though I use it on the back-end).
reply
My favorite thing about it having Silverlight is Silverlight actually worked on Linux better than Flash did. I think I used the Mono version of it though, I don't remember?
reply
Their UI originally was Silverlight which at that time had the best "adaptive streaming" story.
reply
Large companies use more than one language.
reply
deleted
reply
deleted
reply
I assume it's because Go is so opinionated? I experimented with it and found it almost boring to write, but I strangely loved it. Now in the AI era I crave the forced uniformity.
reply
Which exact documents to you give them. The single style guide? The references as well? The additional detail listed in the guide as links?

I'm curious to try your proposal, I just want more specifics.

reply
I've made a pr to my agent trying to implement it. it did fine in blind a/b tests so just going to go forward

https://github.com/notque/vexjoy-agent/pull/908

reply
When you give those resources to your coding agent, do you give them URLs? Or work with local versions?

I've found a lot of success pointing claude at locally downloaded docs over llms.txt URLs but not sure how to scale the pattern for a bigger project.

reply
A sort of an amateur I found Go to be really good when used with language models. Simplicity and tooling helps I suppose and I expected it to. However I was pleasantly surprised with how they are also pretty good with Flutter and Dart. Again good tooling, good documentation and perhaps not much historical baggage like a python or a PHP would have. And no stack overflow to speak of pretty much.
reply
I have a question: why do you think Go is better compared to other languages?

After all, learning a new language takes a lot of time. While basic syntax is common and quick to pick up, mastering a language's specific mental model requires a significant time investment, which is why I've used Go before but never seriously.

My interest was piqued recently when I heard about TypeScript tooling being ported to Go, and I know it is incredibly fast. However, where do the results claiming that AI agents generate superior Go code actually come from? Is it a fair, apples-to-apples comparison?

Since Go is a very small language with only 25 keywords, the way you write code is extremely standardized. Because of this, I would assume it naturally produces a lot of excellent best practices and conventions, but I'm not sure if there are actual, direct code examples proving this

reply
> why do you think Go is better compared to other languages?

I didn't say that. :)

> where do the results claiming that AI agents generate superior Go code actually come from?

Like I said - reports from users.

> Is it a fair, apples-to-apples comparison?

No - these are reports from users, not a systematic analysis.

reply
>> why do you think Go is better compared to other languages?

> I didn't say that. :)

I call this the Go paradox.

I simultaneously believe we should reach for it 80% of the time to solve common collaborative problems. And being a poorer language is actually an asset in these cases.

However, in doing so, we get rusty lose our fluency in more expressive, perhaps even better languages.

reply
> Like I said - reports from users.

How does that work? Are they generating the same project in different languages and comparing the results? What does it mean for the code to be "better"?

reply
Ah, I see. I misunderstood.Is the report from an internal source, so it can't be shared? If not, I'd appreciate it if you could send me a link so I can look into it too.
reply
it’s probably just some informal Slack messages between colleagues that is being described as “reports from users”. There is no Report here
reply
Yes, this. =) I talk to Go users around the company all the time. Their feedback has been in this direction for a bit now.
reply
But isn't this expected from users that like a certain language? Won't you also hear this response from Rust users that like Rust?
reply
Exactly. I only count opinions from people who have deeply used the two langs they're comparing and can express what exactly was wrong with one of them for their task.
reply
You are being downvoted but I think this is correct. I doubt Netflix is really doing a double blind RCT on which languages produce better AI pull requests. How would that even work, have two versions of each service in different languages?

It's anecdata and maybe, MAYBE, a spreadsheet. Or a Google Form somewhere.

reply
Go is really amenable to being used to write code by LLMs. New code takes time to pick up, but the LLM is a quick study.

In my opinion, it has little to do with the speed of the language. The large quantity of source code to train on is quite helpful, but I think it's something else.

There are three things that I think make it well suited to LLM authorship -

1) static typing and a quick compiler - a variable can't change type after it's declared (unlike Python) makes Go more robust compared to dynamic languages. You (almost) always know what the type of a variable is. And the quick compiling with hard-stop errors means that the LLM gets a solid signal for each round.

2) It's quite opinionated, syntactically. There is generally one way that Go lang code is supposed to look. That means it's pretty easy to read as well as write. The lack of things like operator/method overloading make it an easy language to reason about.

3) the stdlib and limited dependencies. Dependency trees tend to be shallow, and because of the static linking (by default), you can generally be confident that what you wrote will run.

reply