Why might collection.map call the stdlib generic overload instead of a protocol-extension map you wrote?
Mental model. The standard library owns the road. Your side street is only taken if you name it something the driver is actually looking for.
Overload resolution prefers the more specialized, statically-known candidate. The stdlib's map is generic over Sequence and gets specialized for Array; your extension on Collection (or on any Collection) goes through a witness or is shadowed entirely.
The practical lesson: never silently shadow a stdlib method name. Wrap the type or use a distinct, descriptive name. If you must add behaviour, put it in a protocol requirement so the dispatch is predictable.
Common traps
- “Swift picks the most specific overload.” It picks by a complex ranking of constraints, not by “closest to my type”. Adding a method can also change which overload existing code resolves to — a source-breaking surprise.
- Testing only through the concrete type. The bug often appears only through the existential or generic path.
They might follow up with
- How do you debug it? Put a breakpoint in both implementations and inspect the static type at the call site.
- What is the safer pattern? A free function with a distinct name, or a wrapper type with its own API.
Related questions
- 1.3.3 Protocol extension vs inheritance for default behaviour — what are the tradeoffs?
- 1.4.7 What is generic specialization? When does it not happen?
- 1.11.1 Static vs dynamic dispatch in Swift?
← Protocol extension vs inheritance for default behaviour — what are… What is an associated type? Why can’t you write let x: MyPAT easily? →