Lies we tell ourselves to keep using Golang (2022)
A widely read critique of Go’s design reignited debate over whether the language’s much‑praised simplicity and explicit error handling are strengths or liabilities in real‑world systems. Supporters argue that Go’s minimalism, tooling, and fast compilation make it ideal for scalable backend services and large teams, while critics point to verbose error patterns, weak type features (e.g. lack of sum types), awkward FFI, and concurrency footguns that become painful in complex projects. Many compare Go to Rust, Java, C#, and newer languages like Zig or Gleam, highlighting a broader tension between “boring,” easy‑to‑learn tools and more powerful but complex type‑safe alternatives.
Error handling: explicit vs exceptions vs sum types
- Large subthread contrasts Go’s
if err != nilstyle with exceptions and Rust-styleResult/Option. - Supporters of Go like explicit, local error handling and a single
errorinterface type; they see exceptions as “hidden gotos” that are overused and hard to reason about. - Critics say Go’s pattern is verbose, dominates code, and often degenerates into copy‑pasted “bubble up” logic with little real handling; errors are frequently ignored or turned into opaque strings.
- Many praise Rust-style sum types (
Result<T,E>,Option<T>) plus the?operator as a better compromise: explicit in types, concise to propagate, and good for composition and exhaustive handling. - Some argue exceptions are still ergonomically superior in many domains, especially when paired with good stack traces and RAII/TWR constructs.
Type system, sum types, and defaults
- Multiple commenters think Go’s type system is “prehistoric” by modern standards: no native sum types, weak generics history, pervasive
nil, default zero values that can mask bugs. - Lack of sum types and non‑nullable references is seen as harming API clarity and error modeling.
- Others counter that Go’s minimalism and interfaces are adequate for its target use (servers, tools), and stronger type systems introduce complexity and function “coloring.”
Simplicity, readability, and verbosity
- Fans emphasize Go’s small surface area, fast compilation, and consistent tooling; they find it easy to onboard juniors and to maintain large codebases.
- Critics argue Go is “easy, not simple”: complexity is pushed onto developers via boilerplate, implicit pointer/value semantics, slice quirks, and multiple return values used as ad‑hoc tuples.
- There is disagreement whether Go’s error-heavy style improves readability or buries “happy path” logic in noise.
Ecosystem, tooling, and “island” concerns
- Many appreciate the integrated toolchain (
go build, modules, fmt, race detector, profiling) and static binaries. - Others complain Go is an “island”: CGO and FFI are painful, libraries often re‑implement functionality, and interop with other ecosystems is awkward.
Comparisons with other languages
- Rust is frequently invoked as an alternative with stronger safety and error handling but acknowledged higher complexity and slower onboarding.
- Java and C# are seen by some as closer competitors to Go for backend services; others avoid them due to ecosystem complexity or runtime overhead.
- Several mention alternatives (Zig, Nim, Crystal, Gleam, F#, C# AoT, etc.) but note that none yet combine Go’s deployment story with a richer type system at Go’s level of ecosystem maturity.
Meta: article tone and language wars
- Some agree with most technical criticisms of Go but still choose it pragmatically for productivity.
- Others find the article biased toward Rust, rhetorically aggressive, and too dismissive of trade‑offs.
- Multiple comments note how emotional and polarized language discussions become, and stress “use the right tool for the job” over language identity.