An Honest Review of Go (2025)
Site / Rendering Issues
- Several commenters report missing letters (notably “t”) or garbled text in Safari and some Firefox builds.
- Others on Firefox (Linux, Android, Windows) see no issue.
- Consensus guess: the site’s WOFF2 variable font trips up certain Safari versions; newer Safari appears to render it fine.
- Author later acknowledges having “hacky” HTML/CSS and not being surprised some browsers choke.
Go’s Design Goals and Overall Feel
- Many agree Go’s concurrency via goroutines/channels is elegant and much nicer than manual mutexes.
- Some find Go not “fun” to write compared with FP-oriented languages (Clojure, Rust, Julia), citing its deliberate lack of abstractions.
- One view: Go’s “original sin” was targeting C/C++-level devs with minimal CS background, aggressively pruning abstractions that take longer to explain.
Enums, Sum Types, and Pattern Matching
- Lack of first-class enums/sum types is a major recurring complaint.
- Idiomatic “enums” are typed
constvalues withiota, but:- They’re not closed sets; you can’t rely on exhaustiveness.
- They’re hard to enumerate generically.
- Several argue modern “enums” really mean sum types + exhaustive pattern matching (as in Rust/Swift/Gleam), which Go lacks.
- Others counter that most real-world enum use is just naming magic constants; Go’s approach is sufficient and simpler.
Error Handling Debate
- Many comments say the blog’s criticism of Go errors rests on misunderstandings:
- Error values are interfaces; you can inspect concrete types via
errors.Is/errors.Asor type assertions. - You don’t need to parse error strings in idiomatic code.
- Error values are interfaces; you can inspect concrete types via
- Others agree with the author’s deeper complaint:
- No static guarantee you’ve handled all relevant error variants.
- Error sets are open-ended; documentation, not types, defines which errors may appear.
- There is strong disagreement over verbosity and readability of pervasive
if err != nil:- Some see it as explicit, simple, and “forces you to be a better programmer”.
- Critics say it clutters control flow, loses stack context, and is less clear than Result/Option-style models.
Standard Library, Tooling, and Ecosystem
- Broad praise for Go’s batteries-included tooling: testing, benchmarking, profiling, formatting, race detection, cross-compilation.
- Several note you can build production HTTP APIs and services with only the stdlib (HTTP, JSON, crypto, pprof, context, etc.).
- Compared to languages where every project rots under dependency churn, Go programs are said to keep compiling across versions.
- Some push back that the stdlib is “small” versus the JDK, but defenders argue its capability-per-API-surface is high.
Go vs. Rust, Python, Elixir, C#
- Rust is frequently cited as “more fun” with better type system, enums, and pattern matching, but:
- Tooling and ecosystem are more fragmented (need many crates, heavy dependencies like Tokio).
- Cross-compilation and C dependencies can be painful.
- Go is preferred when teams come from Java/Ruby/TypeScript and need simple, fast, low-memory services.
- Elixir/Erlang concurrency is praised; however, lack of static types is seen as a scaling downside compared to Go.
- C#/.NET is mentioned as approaching Go’s “all-in-one” experience in more recent versions.
Proto / Enums Historical Speculation
- One long subthread speculates Go’s enum story is influenced by protobuf:
- Proto field numbers and enums are sparse, versioned, and not truly enumerable.
- This may have nudged Go toward open, non-exhaustive “enum-like” constants instead of closed, strongly-typed enums.
- Others question this link and argue open vs. closed enums is primarily an API-compatibility and design-choice tradeoff.