Remix.run Logo
blixt a day ago

I feel like the author is fed up with being disagreed with, yet makes very opinionated statements about how others should (or will, at some point in the future) feel. They make good points about problems in Go, but I gotta say they also make a lot of points that might never become a problem at all.

I've written code that runs in production for 20 years now and every language I ever shipped software with, from ASP, PHP, and C# to Swift, TypeScript and Rust, one thing is always true: there's a pretty good reason the language was picked, and yet a long list of grievances. The reason a language is picked is most often productivity, some belief that software will ship more safely and often if we pick this language. Of course that belief can be uninformed and proven wrong later. But it's really hard to say, for any language, that "you will regret picking this language".

Sure maybe you shouldn't pick PHP for your new startup backend because you'll have a harder time finding developers. Maybe you shouldn't pick Python because despite asyncio there's still that one call you accidentally did that will lock up your highly concurrent service. Maybe you shouldn't pick Java because it's got verbose factories and something about billion dollar mistakes. Possibly picking Rust is a mistake because your developer team will spend 80% of their time fighting the borrow checker. Picking Swift to do your backend seems rather odd, and C++ is too risky with all its undefined behaviors and segmentation faults. Beware of Node.js unless you're ready to dedicate beefy RAM instances to it.

That is of course all hyperbole, I've seen productive code in all of the above languages. And I should add that many of them were not designed any more than Go was, to address one of the author's concerns. I've picked Go many times since it hit 1.0 and I don't regret it, even with production code that is over 10 years old. Go does concurrent processes and I/O really well. The GC works very well for long-running programs with lots and lots of individual goroutines. I also saw developers that had never touched Go enter the code base and make productive edits, which I consider a benefit of Go's simple design (or non-design, as per the author). I've also done similar systems in other languages, especially Node.js, Python, and Rust, but they haven't been as productive in my experience for this use case.

Ironically code written in Rust did wake me up in the middle of the night more than Go did, possibly because it was harder to express the mental model the way originally intended, and instead the code was written to satisfy the computer's memory model. I would still use Rust every day for things where that matters more, but the author seemed to imply somehow avoiding Go avoids unexpected errors, but they happen in every language.

TLDR: Programming languages live on because they make people feel productive. Maybe this feeling is aligned with the business needs, maybe not. But don't go saying that everyone should avoid a language entirely because of your personal experiences.

blixt 8 hours ago | parent [-]

Took some time to read the linked Tailscale blog posts as examples of horrible hacking around Go. And I would agree it's crazy for a product oriented startup to do this, but this team is also made up of people that have contributed a lot to several core parts of the Go runtime.

Since these blog posts were written, Go has made official the interning approach that the netaddr.IP type depended on, now without the horrible pointer hacks, and the IP type itself has been migrated into an official package with even more improvements, now benefitting everyone. The iOS network extension memory problem was a very nice deep dive into what happens behind the scenes (something that is assuredly not perfect in any language) and resulted in a better Go experience for everyone using the language.

So a team pushed the limits of a language and made the language better for everyone out of the box. This happens in most languages, but rarely do you see such approachable blog posts about it, where the solutions are readable in the language itself, and with enough commentary even understandable.

I recommend reading these articles as examples of good language evolution, not as examples of a broken language.