Good union types in Go would probably need types without a zero value

Union / Sum Types vs Go’s Zero Values

  • Central question: can Go have “good” union/sum types without breaking its “every type has a zero value” design.
  • Some argue zero values for unions are either useless (just memory packing tricks) or dangerous / confusing.
  • Others suggest pragmatic compromises: zero value = first variant, or zero value = nil/interface-like “no value”, even if slightly “stupid” but consistent with Go’s other rough edges.
  • Concern: choosing “first variant as default” breaks commutativity (A|B vs B|A differ) and can be a footgun.

Error Handling and Exhaustiveness

  • Several commenters want sum types mainly to improve error handling:
    • Avoid repetitive switch/errors.Is/string-matching patterns.
    • Get compile-time guarantees of “handled all error cases” and easy refactoring when error variants change.
  • Comparisons to Rust, Scala (ZIO/Cats Effect), Zig, Nim:
    • These offer more precise error typing or effect systems, but still don’t perfectly answer “show me all possible errors here.”
    • Some find Rust’s error ergonomics disappointing in practice; sum types can demand lots of boilerplate and wrapping.

Runtime and GC Constraints

  • Big technical objection: Go’s concurrent GC needs to know where pointers are.
  • A tagged union whose active variant changes could change which fields are pointers, racing with the GC if done naïvely.
  • Go previously changed interface representation to avoid similar GC races; unboxed tagged unions might require deep runtime redesign.
  • Boxing every variant (like interfaces) is feasible but adds allocations and undermines performance motivations.

Expressiveness vs Simplicity

  • Many feel Go’s type system is too weak for serious domain modeling (e.g., “make invalid states unrepresentable”; non-zero-only types).
  • Others report very high productivity with Go and view stronger type systems as added cognitive load, especially for large teams of relatively new engineers.
  • Tension: minimal core language vs pushing complexity into codebases (custom patterns, libraries, boilerplate).

Did Go ‘Ignore’ PL Research?

  • Some say Go failed to adopt 40–50 years of known ideas (sum types, richer generics, algebraic data types).
  • Counterpoint: adoption, readability, tooling, GC, and compatibility constraints justify caution; features can’t just be copied from ML/OCaml.
  • Go’s compatibility promise and lack of a story for evolving enums/sums without breaking users is cited as a blocker.

Workarounds and Partial Solutions

  • Current practice: interfaces plus type switches; sealed interfaces with unexported methods; tooling for exhaustiveness checks.
  • Proposed syntactic sugar: special option/result-like constructs using make and type assertions; would still panic on misuse, consistent with other Go nil/zero traps.
  • Some prefer to “just use another language”; others note they’re constrained by employer choices, so they keep pushing for better features in Go.