Why Go’s New Collection Types Are a Game‑Changer, Explained by the Author of Fluent Python
The article analyzes the upcoming Go 1.28 collection proposal #80590, detailing how native Set, Map, Hash and ordered map types will replace manual map‑based sets, improve performance with constant‑time membership checks, enable custom hashers for non‑comparable keys, and simplify code for both developers and AI programming assistants.
For sixteen years Go’s standard library lacked a built‑in Set type, forcing developers to hand‑craft collections using map[T]struct{} or map[T]bool. Luciano Ramalho, author of Fluent Python , presented at GopherUK 2026 a deep dive titled “Sets in Modern Go” that explains the design behind the upcoming collection overhaul.
Proposal #80590 Overview
The Go Collections Working Group, formed at the end of 2025, submitted proposal #80590 to add a family of generic collection types to the standard library. It introduces seven concrete additions:
maphash.Hasher – an interface for custom hash and equality functions (landed in Go 1.27).
container/hash.Map and container/hash.Set – hash‑based generic Map and Set built on the Hasher.
container/heap – a redesigned heap with a better developer experience.
container/set.Set – the primary “standard Set”, a named type of map[E]struct{} that can be assigned to and from the raw map representation.
container/mapset – a low‑level package exposing functions for existing code to reuse.
Ordered map – a map that preserves insertion order.
These types aim to follow Go’s “practicality + simplicity” philosophy while providing a richer API surface.
From Hand‑rolled Code to Set Algebra
Ramalho illustrated a common backend scenario: checking whether a product description contains all search keywords. Before generics, the solution required nested loops, multiple break, return and if statements, leading to high cyclomatic complexity. By treating the problem as a subset test, the same logic becomes a single set operation.
If a product description contains all the words from the search query, display the product.
Similarly, removing already‑in‑cart items from a favorites list is a classic difference operation. The talk argued that once collection abstractions are available, the code shrinks dramatically and AI assistants can generate more concise, correct snippets.
Set Algebra and Language Design
Ramalho reminded the audience that set operations are identical to logical operators: intersection ↔ “and”, union ↔ “or”, difference (no direct logical counterpart), symmetric difference ↔ “xor”. He cited the classic bitset implementation in The Go Programming Language as an example of how set algebra maps to ultra‑fast bitwise operations.
API Details and Naming Conventions
The new container/set.Set type is a named map[E]struct{}. Its methods return a bool indicating whether the operation actually changed the set, a design derived from internal Google code audits. Mutating methods have plain names (e.g., Insert), while immutable variants carry a With suffix (e.g., IntersectionWith) and return a new set.
Ramalho pointed out an inconsistency: the Of(...) constructor in the container/set package returns a named Set, whereas the analogous constructor in container/mapset returns a raw map[E]struct{}. He highlighted this as evidence that the API is still a work‑in‑progress.
F‑bounded Polymorphism
To express methods that return the same concrete collection type, the proposal uses F‑bounded polymorphism. The simplified definition looks like:
type AbstractSet[E any, S AbstractSet[E, S]] interface {
AbstractCollection[E, S]
// …
}This pattern mirrors Java’s Enum<E extends Enum<E>> and ensures that operations such as Intersection return the exact concrete set type.
Custom Hasher Example
The new maphash.Hasher interface breaks the built‑in map restriction that keys must be comparable and use a fixed hash function. A case‑insensitive string set can be built as follows:
type CaseInsensitiveHasher struct{}
func (CaseInsensitiveHasher) Hash(s string) uint64 { return maphash.String(strings.ToLower(s)) }
func (CaseInsensitiveHasher) Equal(a, b string) bool { return strings.EqualFold(a, b) }
s := hash.NewSet[string](CaseInsensitiveHasher{})
s.Insert("Go")
fmt.Println(s.Contains("go")) // trueRamalho criticized the example for mixing strings.ToLower (ASCII‑only) with strings.EqualFold (Unicode‑aware), noting that the two should use the same normalization logic.
Implications for Developers and AI Assistants
Ramalho emphasized that set algebra provides a precise, language‑agnostic vocabulary. Even in languages without native sets, describing a problem in terms of “intersection”, “difference”, or “subset” guides both human developers and AI code generators toward more efficient implementations.
For beginners, learning SQL—another set‑oriented language—can reinforce these concepts.
Key Takeaways
Set algebra yields simpler, faster solutions for common data‑processing tasks.
Go 1.28’s collection types will become the de‑facto standard for generic containers.
The Hasher‑based Map and Set give Go its first truly flexible custom‑equivalence capability.
All the code discussed is still in the proposal stage and may change before the final Go 1.28 release.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
TonyBai
Tony Bai's tech world (tonybai.com). Not satisfied with just "knowing how", we strive for mastery. Focused on Go language internals, high-quality engineering practices, and cloud‑native architecture, exploring cutting‑edge intersections of Go and AI. Gophers who pursue technology are welcome—follow me and evolve with Go.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
