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
nilare 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++
constdone “all the way down”). - Java-style
finalis 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/finalcatches 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 aResulttype with syntactic support. - Defenders argue auto‑propagation hides where errors occur and leaks implementation details unless carefully wrapped.
- Critics want a compact propagation operator (
- 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
tryproposal; 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,
nilsemantics, lack of enums, awkward error handling. - A reinvention of a decades‑old model that ignores more modern PL research.
- “Simple but wrong” in places: zero values,
- 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.