Static polymorphism isn't an imitation of anything. In
canonical OO-speak, "polymorphism" is the ability of different
objects to respond to the same message in different ways.
Polymorphism isn't restricted to OO; it's a well established
concept, first described, I think, in a paper by Christopher
Strachey in 1967. The "reference", as far as I know, is "On
Understanding Types, Data Abstraction, and Polymorphism", by
Cardelli and Wegner
(
http://lucacardelli.name/Papers/OnUnderstanding.A4.pdf). The
concept includes such things as function overloading and
implicit conversions, as well as parametric polymorphism and
inclusion. Roughly speaking, a function or operator is
polymorphic if it can be invoked on different types. (Thus, in
C, the + operator is polymorphic, since I can add integers, or
floating point values.)
In languages that are not restricted to OO, "static"
polymorphism means roughly "the ability of fixed syntax to
mean different things, depending on context."
Formally, static doesn't mean anything when applied to
polymorphism. Informally, it is usually used to mean that the
polymorphism is somehow resolved at compile time, as opposed to
runtime. But even this doesn't mean much when more dynamic
languages are involved, like Lisp. Or for that matter, even in
C++: if I provide a single class interface (no virtual
functions), with several different implementations, in different
DLL's, and choose which DLL to load at runtime, is that static
polymorphism, or dynamic?
This kind of polymorphism is "static" in the sense that the
mapping is implemented at compile-time. The traditional
example is overloaded functions:
int square(int const i) { return i * i; }
double square(double const d) { return d * d; }
/* Function resolution depends on the type of n.
* Which function to call is determined at compile-time.
*/
square(n);
In statically typed languages that support operator
overloading, viz. C++, static polymorphism can be more
subtle:
/* This syntax may or may not imply a function call.
* The determination is made at compile-time, though
* the operation may be performed at run-time.
*/
v += 5;
I think you mean that the syntax may or may not imply using
semantics defined by the user. I've used machines on which a
function would be called for the above even if v had type double
or long. The syntax for defining user defined semantics in C++
is, however, that of a function (with a somewhat special name).
Note that in C++, such a statement may involve all four types of
polymorphism: it clearly involves overloading; if v is a double,
it also involves coercion; if the operator+= function for type v
is a template, it involves parametric polymorphism, and if the
operator+= function is virtual, in involves inclusion
polymorphism. In C++, the first three are normally resolved at
compile time (but consider my example using DLL's, above); the
last is normally not resolved until runtime (but if the compiler
can determine the dynamic type of v at compile time, this might
not be true either).