diff --git a/docs/WhatsNew.md b/docs/WhatsNew.md index 6bad903..18851a8 100644 --- a/docs/WhatsNew.md +++ b/docs/WhatsNew.md @@ -92,3 +92,17 @@ A side effect: a function parameter declared `(own T)` whose only in-body use wa Two modules in one workspace can each declare a type with the same bare name (for example, both declaring `type Foo`) and carry their own type-class instances — both now register under their owning modules and stay distinct. Before this round, one declaration silently overwrote the other in an internal index and the loser's instance tripped a misleading "duplicate instance" error. Internal housekeeping in the same round: a structurally unreachable validation path was removed, and a previously implicit design decision about the type checker's overlay structure was written down. + +## 2026-05-13 — Two libraries can each declare their own type class + +A workspace can now have two libraries each declaring `class Show` (or `class Eq`, `class Ord`, …) with their own method, and both can ship instances for overlapping types. Before this round, the loader rejected the workspace the moment two classes anywhere declared the same method name. A workspace-global ban that was never load-bearing for correctness — just a workaround making bare method calls unambiguous. + +The replacement is type-driven dispatch at the call site. When `show 42` is reached and only one class in scope declares `show`, the call resolves automatically. When two do, the checker first narrows by the argument's type (only one class might have an instance for `Int`); if that still leaves more than one, it reports the ambiguity with the candidate class names and asks the author to disambiguate via `..show 42`. A class method that happens to share a name with a free function is handled the same way: the free function wins by the existing precedence rule, but the author gets a warning so an accidental shadow doesn't pass silently. + +This unblocks the deferred prelude rewire — the prelude is free to ship its own `class Show` now that it no longer collides with the 14 test fixtures that historically declared a user-class named `Show`. + +The new dispatch model is now anchored in the language reference as a named subsection; the related class-reference fields (`InstanceDef.class`, `Constraint.class`, `SuperclassRef.class`) follow the same bare-for-same-module / `.`-for-cross-module rule that type names already follow. + +Bench all-green; the noise envelope on a tail-latency metric continues for the sixth consecutive audit and remains baseline-pristine pending a clear signal-vs-variance call. + +Queue back to user-direction: the prelude-rewire milestone is ready for a fresh design pass against the new dispatch model.