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 const values with iota, 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.As or type assertions.
    • You don’t need to parse error strings in idiomatic code.
  • 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.