Skip to content

(Potential) Fully immutable collections: builders and no Add #42

Open

Description

@Trosper3

Problem

UtilCollection is mutable. #11 (the fix for #9) guards against the worst effect: a collection freezes the first time it's hashed, and after that Add and the indexer setter throw InvalidOperationException. But that's a runtime check. The API still offers Add on every collection, so a mistake shows up only when the code runs, and every collection carries the frozen flag and the checks that go with it.

Wanted

Fully immutable collections, so changing one after it's built isn't possible at all:

  • Builders for sets, lists and multisets (feat(collections): add multisets #17). You add elements to a builder, then call Build() to get an immutable collection.
  • No Add or indexer setter on the collections themselves. Freeze() / IsFrozen() either go away or become no-ops.
  • The parser builds with builders internally, so parse() results stay as they are for callers that only read them.
  • The hash is computed once, when the collection is built, which takes over from fix(collections): hash sets independently of element order #11's cached hash and volatile flag. Documentation/threads.md gets simpler: every built collection is safe to share.

Why not now

It's a breaking change. Redux code that builds UtilCollections with Add would have to switch to builders. #11's freeze-on-hash guard covers correctness for 0.2.0, and Redux's full suite behaves the same with and without it, so this can wait for a release that's allowed to break the API.

Open choices: whether to keep Add as a deprecated shim for one release, and whether to build on System.Collections.Immutable or keep our own types.

Redux context

Redux would need a migration pass wherever it builds collections by hand. This also helps the high-performance computing work starting on Redux: immutable instances can be shared across threads without any rules about when they freeze.

Raised in the mutability discussion on #11.

Activity

  1. added this to the 0.4.0 milestone on Oct 16, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions