From c8cf5f5e76e0f28ae69643211ce6d6b8c8d6e0eb Mon Sep 17 00:00:00 2001 From: Derek Corniello Date: Wed, 15 Jul 2026 22:17:40 -0700 Subject: [PATCH 1/2] docs: record why `{}` is a set and `{:}` is a map The collections design doc described nesting and reference counting but said nothing about literals, so the one genuinely non-obvious decision - that brace syntax is shared between map and set, and how Mux breaks the tie - was written down nowhere. Explain the tradeoff: the compiler used to infer which one `{}` meant from the expected type, which required a third EmptySetOrMap type threaded through semantics and codegen plus a span-keyed override map, and still had no answer when there was no expected type. `{:}` resolves it in the grammar instead. --- docs/design/collections.md | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/docs/design/collections.md b/docs/design/collections.md index db94105..feb7cdd 100644 --- a/docs/design/collections.md +++ b/docs/design/collections.md @@ -11,6 +11,29 @@ arbitrary nesting (e.g. `list>>`). | `map` | `BTreeMap` | key/value pairs, sorted keys | | `set` | `BTreeSet` | unique elements, membership | +## Empty literals: `{}` is a set, `{:}` is a map + +`map` and `set` share brace syntax, so an empty `{}` is ambiguous on its face. +Mux resolves this in the grammar rather than the type system: **`{}` is always +the empty set, and the empty map is spelled `{:}`.** + +The alternative - inferring which one `{}` meant from the surrounding expected +type - is what the compiler used to do, via a third `Type::EmptySetOrMap` that +every stage had to carry and a span-keyed override map that rewrote the type +after the fact. It worked, but the ambiguity leaked into semantics and codegen, +and an empty literal with no expected type to resolve against had no answer. +`{:}` removes the ambiguity at the source, so `EmptySetOrMap` and the override +machinery are gone (mux-compiler#266). + +Consequences worth knowing: + +- `{}` in a map-typed position is a compile error, not an inference. Both + directions of the mix-up get a targeted diagnostic naming the other spelling. +- Empty literals still need an explicit type - `{:}` alone cannot infer `K`/`V`, + the same way `[]` cannot infer its element type. +- Nesting follows the same rule per position: `map> x = {1: {}}` + is a map of sets, while `map> y = {1: {:}}` is a map of maps. + ## Why BTree, not Hash `map` and `set` use the B-tree variants rather than hash maps for: From bdb3cc19786b1630e0a6d7bc2c10e4032cac5011 Mon Sep 17 00:00:00 2001 From: Derek Corniello Date: Wed, 15 Jul 2026 22:22:34 -0700 Subject: [PATCH 2/2] docs: index the empty-literal rule in llms.txt llms.txt is how agents decide which doc to open, so a rule that is not named in the description is a rule they will not find. The collections entry listed BTree and nesting but not literals. --- llms.txt | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/llms.txt b/llms.txt index 1e33d29..0cfc935 100644 --- a/llms.txt +++ b/llms.txt @@ -15,7 +15,7 @@ repo owns the facts that span more than one repo. - [Monomorphization](https://github.com/muxlang/mux-context/blob/main/docs/design/monomorphization.md): compile-time generics - [Object system](https://github.com/muxlang/mux-context/blob/main/docs/design/object-system.md): ObjectRef, type registry, static interface dispatch - [Operators](https://github.com/muxlang/mux-context/blob/main/docs/design/operators.md): short-circuit lowering, operator overloading -- [Collections](https://github.com/muxlang/mux-context/blob/main/docs/design/collections.md): list/map/set, BTree rationale, nesting +- [Collections](https://github.com/muxlang/mux-context/blob/main/docs/design/collections.md): list/map/set, BTree rationale, nesting, empty literals (`{}` is a set, `{:}` is a map) - [Error handling](https://github.com/muxlang/mux-context/blob/main/docs/design/error-handling.md): result/optional layout - [Runtime panics](https://github.com/muxlang/mux-context/blob/main/docs/design/panics.md): process-terminating failures, the panic format, why no baked source snippet - [Modules](https://github.com/muxlang/mux-context/blob/main/docs/design/modules.md): import resolution, name mangling, module init