I am learning some polymorphism.
The wiki page for rust addresses trait
is a method to achieve ad hoc polymorphism, and the page for ad hoc polymorphism says function overloading
is an example of ad hoc polymorphism.
Based on my current level of understanding a function is ad hoc polymorphic if providing different types of parameters will invoke different implementations. But trait
and function overloading
seem so different: trait
add constraints on type parameters, any type implementes the trait
is acceptable, while function overloading overload on the concrete type, any types that are not overloaded are not acceptable.
Can I say trait
and function overloading
achieve ad hoc polymorphism in the opposite direction? As trait
is by specialization and overloading
is by generalization?
PS: In c++, template specialization can also provide different implementations based on type parameter passed in, is that also an example of ad hoc polymorphism?
Implementing a trait involves providing an implementation of a behavior, which is type-specific and separate from other implementations ("ad hoc"), and which may be invoked with the same spelling at the call-site as other implementations ("polymorphic"). It's in the same direction as function overloading.
In C++, you might provide overloads to achieve ad hoc polymorphism:
And you can do the same with traits in Rust:
The "other direction" I think you're referring to is being able to constrain generics by what behaviors the types support. In Rust, this looks like:
C++ has an analogy:
Constrained generic functions are not ad hoc polymorphism because they have one implementation which applies to all argument types that implement whatever requirements are placed on them.
In summary, traits provide both ad hoc polymorphism and constraints for generic functions, and some languages like C++ use different devices to achieve the same ends. Ad hoc polymorphism in C++ is typically achieved with function overloading. Template specialization can also achieve it.