Love for Go and Rust rant!
Source: Dev.to
Warning: rant!
Introduction
I’m so tired of this shit. Every few weeks, some Rustacean slithers in here with their smug “but have you tried fearless concurrency?” spiel, acting like Rust is the Second Coming of programming languages that finally fixes everything wrong with the world. Newsflash: it’s not. It’s a bloated, over‑engineered mess masquerading as a panacea, and its concurrency story is one of the biggest hyped‑up lies in modern PL discourse.
Go’s Concurrency Model
Go (and, yeah, Erlang/BEAM before it) actually got concurrency right.
- Goroutines are dirt‑cheap.
- Channels are built‑in and idiomatic.
- The scheduler is battle‑tested.
You can spin up thousands—hell, millions—of concurrent tasks without your brain melting or the compiler throwing a tantrum. It’s simple, predictable, and scales to real‑world production systems without needing a PhD in lifetime annotations.
Rust’s Concurrency Model
Rust? Oh boy. They brag about “fearless concurrency” because the borrow checker catches data races at compile time. Cool story, bro. But guess what? That’s only half the battle—and a tiny half at that.
Real concurrency bugs aren’t just shared mutable state; they’re deadlocks, livelocks, starvation, priority inversion, and worst of all: blocking the executor.
In Rust’s dominant async ecosystem (Tokio, async‑std, whatever flavor of the week), everything’s cooperative multitasking on a thread pool. One idiot calls a blocking function—.await a future that secretly does std::thread::sleep, reads a file synchronously, or hits some crate that blocks under the hood—and BAM, you’ve starved the entire runtime. Your “massively concurrent” app grinds to a halt on one thread while the rest sit idle.
It’s the exact same foot‑gun as Python’s GIL or Java’s thread‑blocking nonsense. Rust doesn’t prevent it; it just makes you chase it down manually, wrap it in
spawn_blocking, or pray your dependencies are perfectly async‑all‑the‑way‑down (spoiler: they’re not).
And don’t give me that “but Send/Sync traits!” crap. Traits don’t magically make third‑party libraries non‑blocking. One lazy dev (or one outdated crate) and your fearless concurrency is as vulnerable as any GC’d language.
Comparison
| Aspect | Go | Rust |
|---|---|---|
| Concurrency primitives | Goroutines, channels (built‑in) | Futures, async runtimes (Tokio, async‑std) |
| Blocking pitfalls | Hard to accidentally block the whole system | Easy to block the executor with a single sync call |
| Compile‑time safety | Memory safety via garbage collector | Borrow checker guarantees memory safety |
| Developer experience | Fast compile times, single binary, readable code | Steep learning curve, lifetimes everywhere, verbose async boilerplate |
| Typical use‑case | Servers, back‑ends, networked services | Low‑level systems where zero‑cost abstractions and no GC pauses matter |
Rust’s borrow checker is great for memory safety (congrats, you reinvented GC without the GC), but it comes at the cost of endless fighting the compiler, lifetimes in every signature, and async code that’s “colored” and infectious, turning your whole codebase into a pin‑projecting nightmare.
Conclusion
Go gets shit done. Fast compile times, single‑binary deploys, boring readability that onboards new devs in days, and concurrency that’s actually enjoyable. Rust? Steep learning cliff, borrow errors that make you question your life choices, and a community of evangelists who think verbosity = virtue.
Rust is fine for what it is: low‑level systems where you need zero‑cost abstractions and no GC pauses. But for servers, back‑ends, networked services—the stuff we do in r/golang—it’s overkill wrapped in hype. Stop shilling your cult language here. We have goroutines. We have channels. We have simplicity that scales.
Go is king. Rust is just the loud kid in the back yelling “but my ownership model!”
Downvote me, Rustbucks. I’ll be over here shipping code while you’re still wrestling the compiler.