The standard definition of ad-hoc polymorphism imputed to Strachy, where:
Strachey chose the adjectives ad-hoc and parametric to distinguish two varieties of polymorphism [Str67].
Ad-hoc polymorphism occurs when a function is defined over several different types, acting in a dif- ferent way for each type. A typical example is overloaded multiplication: the same symbol may be used to denote multiplication of integers (as in 33) and multiplication of floating point values (as in 3.143.14).
That is from the Wadler paper where typeclasses are formalized. Typeclasses and Traits are the implementation details for those function symbols that vary in implementation for each type. The restrictions on the types (like which types implement a trait or have a type class defined for it) are the types the symbol can be used on.
You seem to be focusing on the ‘arbitrary set of types’ point, but the only connection between the types accepted by Rust’s generic functions (which are functions that accept a type provided it has some trait) are that they take types which have an impl for that trait.
I think there is a bit of ambiguity regarding the term ad-hoc polymorphism at play. You seem to think the trait/typeclass implementation of ad-hoc polymorphism (which was invented to formalize a well behaved class of ad-hoc polymorphic functions) makes it no longer ad-hoc. My position echos Wadler, it’s still ad-hoc but just less ‘ad-hoc’ (i.e. more formalized).
It comes to this phrase about a function "acting in a different way for each type".
In C++ there are literally three separate implementations of std::string's contains method for three type signatures. This is pretty clearly what is being discussed as "acting in a different way".
In Rust there's just one, here's the entire function body of contains: pat.is_contained_in(self)
OK, well that's just buck passing right? Clearly this is_contained_in() method on Pattern is really just the contains() implementation, we're passing the work to this function that as you point out needs to be implemented by each of the matching types for Pattern.
Sure enough Pattern implementations although they're not forbidden from implementing is_contained_in themselves, do not in fact do that, they just implement into_searcher. Our hypothetical Jpeg type can provide a suitable into_searcher implementation which results in a Searcher for the Jpeg somehow, without knowing what contains() or split_once() or trim_start_matches() do, and now they will work on Jpegs.
So the "acting in a different way for each type" for contains() ends up only being because of details about the inner behaviour of that type, which is exactly parametric polymorphism so far as I can see.
Strachey chose the adjectives ad-hoc and parametric to distinguish two varieties of polymorphism [Str67]. Ad-hoc polymorphism occurs when a function is defined over several different types, acting in a dif- ferent way for each type. A typical example is overloaded multiplication: the same symbol may be used to denote multiplication of integers (as in 33) and multiplication of floating point values (as in 3.143.14).
That is from the Wadler paper where typeclasses are formalized. Typeclasses and Traits are the implementation details for those function symbols that vary in implementation for each type. The restrictions on the types (like which types implement a trait or have a type class defined for it) are the types the symbol can be used on.
You seem to be focusing on the ‘arbitrary set of types’ point, but the only connection between the types accepted by Rust’s generic functions (which are functions that accept a type provided it has some trait) are that they take types which have an impl for that trait.
I think there is a bit of ambiguity regarding the term ad-hoc polymorphism at play. You seem to think the trait/typeclass implementation of ad-hoc polymorphism (which was invented to formalize a well behaved class of ad-hoc polymorphic functions) makes it no longer ad-hoc. My position echos Wadler, it’s still ad-hoc but just less ‘ad-hoc’ (i.e. more formalized).