I've Soured on Go

13 hours ago 2

I've used Go professionally for about 5 years now. I probably won't be using it or recommending it in future.

Before the PLT folk get too excited, no it's not because there's no monads, or that the type system is stuck in the 70s (sorry!).

Why I like(d) Go

The biggest advantage of Go is actually why people don't like it - its low abstraction ceiling. In a team setting, with varying skill levels, this means that you get much more homogenous code. Yes, there's no elegance, and there's a ton of boilerpate, but boilerplate can be generated by LLMs.

Homogenous code is easy to understand code. There's less bikeshedding. If you want to get 20 junior-mid developers of varying skill levels to produce shareholder value, then Go is a great choice. If you have more complicated languages, you definitely need someone in charge with strict standards, and a shared idea of 'taste'. Otherwise you end up with a million different idiosyncrasies.

Performance is also 'good enough' - it's not the fastest language ever, but it's very easy to write code that does a good job performance wise.

What Go is bad at

The second you leave the very narrow window of backend services, you start seeing holes in the usefulness of Go. It does compile to a native binary, but there's a lot of glaring holes where you'd probably want to use a different language anyway.

WASM!

Go currently supports WASM, but ships the whole runtime including the garbage collector. A hello world binary is huge and bloated. This essentially makes it a non-starter. Unfortunately this also rules out the excellent Cloudflare Workers ecosystem.

Go has issues with WASM-GC, and it is unlikely to be fixed anytime soon. At time of writing the issue has been open for 2 years. TinyGo does a better job at this, but has fundamental language limitations like no reflection that makes it difficult to use for anything non-trivial.

Web UI libraries

There's no Web UI library for Go. If you want to build a Web app, you will need to write JavaScript. HTMX is fine for basic things, but you will almost certainly still need to write JavaScript for more complex UIs.

What I am using instead

I'm currently all-in on TypeScript, with sprinklings of Rust for performance critical sections - or places where WASM makes sense. For example, I'm using Rust compiled to WASM for its excellent cryptography libraries. This seems to be the best of both worlds - the performance of Rust and the ease of use of TypeScript. With these two languages, I just don't feel the need for Go anymore.

TypeScript's ecosystem is getting really good

Tooling for TypeScript has gotten a lot better. Both Bun and Deno have standard libraries and tooling that makes it far less awful to work with. Libraries have gotten a lot more mature and stable. The days of crappy NPM packages are over. Things like Effect bring real FP to the ecosystem. Arktype makes validation a breeze.

TypeScript is catching up to Go's performance

Bun and Deno are doing great in the performance realm. Both of them are now far closer to Go in terms of performance than Node ever was. Take benchmarks with a very large handful of salt, but this example has Bun within 2% of Go's performance in optimal conditions.

One performance bottleneck is IPC with shared memory when you have multiple worker threads. This is one of the reasons that TypeScript is rewriting its compiler in Go. However, this is not relevant for many backend services & use cases - where you tend to not need a ton of communication between threads.

Rust is catching up to TypeScript's portability

Rust is already amazing for WASM, but it's also catching up to TypeScript. It's the only language which has a realistic chance of being able to be used for a full-stack web application, with libraries like Dioxus and Leptos. Maybe in a few years I'll drop TypeScript entirely.

The future?

It's really hard to predict the future, but it seems weird that we're still using languages optimized for being easy to read by humans. TypeScript just has the most training data at the moment, but there's no particular reason why it should be the 'default' for LLMs. Go seems to be in a weird spot where it's not as easy to write as TypeScript and not as performant as Rust. This matters for humans, but shouldn't make a difference for machines.

LLMs Should Be Rustmaxxing

Did you know that SWEBench is just Python pull requests?

I'm glad to see stuff like multi SWEBench which uses many languages.

If it was easier to write Rust code with LLMs, I'd be using Rust for everything. Right now they're just too good at TypeScript to use anything else.

Read Entire Article