Good-bye core types; Hello Go as we know and love it

Sum types, nil, and zero values

  • Many commenters want proper sum/union types plus exhaustive switch/pattern matching, citing OCaml/F#/Rust as benchmarks.
  • Current interface + type-switch “sum type” patterns are seen as cumbersome and error‑prone because interfaces are nilable; wrappers to avoid nil are also awkward.
  • Discussion of the official sum-type proposal notes that every Go type must have a zero value; for sum types that likely means nil. Some call this “ridiculous” in 2025, others argue it’s forced by Go’s backward‑compatible zero‑value design.
  • Long subthread on how languages without null (Rust, some MLs) rely on stricter initialization rules and more complex semantics; retrofitting that into Go would add significant complexity.

Immutability and const semantics

  • Several people wish for runtime immutability (like Rust’s immutable bindings or C++ const done “all the way down”).
  • Java-style final is criticized as only protecting the reference, not object state, and as giving a false sense of safety unless the whole object graph is deeply immutable.
  • Others argue even shallow const/final catches many bugs and is better than nothing; Go is viewed as weaker than Java/Rust/C++ here.
  • Reflection-based workarounds are acknowledged but dismissed as a bad reason to avoid language support.

Error handling debates

  • Heavy debate over Go’s if err != nil {} style:
    • Critics want a compact propagation operator (?-like) or a Result type with syntactic support.
    • Defenders argue auto‑propagation hides where errors occur and leaks implementation details unless carefully wrapped.
  • Several people note that good error APIs need clear contracts and wrapping at the right abstraction level regardless of language syntax.
  • Some lament the rejection of Go’s try proposal; others say most Go users didn’t see the current style as a problem.

Generics design and limitations

  • Some appreciate Go’s very conservative generics: they exist but are constrained, which reduces “type‑level cleverness” seen in C++/TypeScript.
  • Others call them “half‑baked”, pointing to:
    • No generic methods with their own type parameters on types.
    • Interactions with interfaces, AOT compilation, and vtables that make richer designs costly.
  • Comparisons are drawn to Haskell type classes, Rust traits, C# generics; several argue Go consciously avoided that level of sophistication.

Go’s philosophy: simplicity vs power

  • Supporters praise:
    • Very stable spec and backward compatibility.
    • Fast compilation and near “scripting-level” iteration speed.
    • A small, easy‑to‑parse language that mid‑size teams can maintain.
  • Detractors describe Go as:
    • “Simple but wrong” in places: zero values, nil semantics, lack of enums, awkward error handling.
    • A reinvention of a decades‑old model that ignores more modern PL research.
  • There’s recurring tension between “simplicity for broad teams” vs expressiveness for expert users; some see Go as “a better Java for mid‑tier engineers”, which others find insulting.

Tooling, performance, and ecosystem comparisons

  • Go’s single‑toolchain story (build, test, format) and trivial cross‑compilation are widely praised; contrasted with slower or more fragmented experiences in C#, Java, and C++.
  • Others counter with Rust and C#, which now also have strong integrated tooling and richer type systems, at the cost of longer compile times and higher conceptual load.
  • There’s meta‑discussion about language success: Go’s popularity is attributed both to its design and to corporate backing, with comparisons to Java, C#, C++, and Rust.

AI, garbage collectors, and code quality

  • Brief tangent: someone asks if GC is still necessary now that AI writes code.
  • Consensus in replies:
    • Manual memory management is especially hard for LLMs.
    • LLMs produce a lot of “garbage” code; if anything, GC and safety features are more important in an AI‑assisted world.