I think a subtler point here is that when you write some generic library code, you have no idea how it’s going to be called, so you don’t know if the compiler will be able to figure out the correct runtime types or not. Examples that are simple to present and understand also tend to be easy for the compiler to figure out statically, and ways to prevent the compiler from guessing static types in these situations generally seem contrived. But real life is often not so simple. Often as not, libraries get used in situations where static overloading becomes either incorrect or overly restrictive. So static overloading is fine until it isn’t—and as a library author, which case you’re in is not within your control. As a library user, the perspective is even worse: a library that uses static overloading works in simple cases and fails in ways that are to you as a user, mysterious and hard to predict, as you try to do something more complex.
Another way to understand this may be that static overloading, despite being superficially syntactically similar to multiple dispatch, has zero additional expressive power over not having any kind of overloading. The compiler literally translates static overloading to something you could write in C with no overloading by renaming things. Multiple dispatch, on the other hand, can only be emulated in C by building a runtime dynamic dispatch system using void pointers and lookup tables. There is really more expressive power there. Exponentially more expressive power, in fact: the number of possible specializations of a generic function is the product of the cardinalities of the sets of possible types of all of the arguments to the function, so if there are two possibilities for each argument, that’s at least 2^n
for n
arguments. Single dispatch is linearly more powerful than static because it is proportional to the number possible types of the first argument, so 2
if there are two possibilities. Yet another way to say this is that dynamic multiple dispatch solves the expression problem whereas static overloading does not.