There is, of course,
a problem with the previous example. It may even strike some as quite subtle,
the first time they think about it. Let’s try invoking our “imbibe” operation
in a context where the type of the operands cannot be statically determined.

In fact, this code
not only will not run, it won’t even compile. This is because while the first
operand to imbibe, the receiver, the Carouser, is dispatched using runtime
polymorphism, the second, the Libation, is resolved using static overloading,
which is a horse of an entirely different color.

The implementations
we’ve seen are really nothing but “name mangled” single-dispatch
invocations under the hood.