A polymorphic function accepts arguments of different types, but has
the same semantics (and usually implementation) regardless of the
types of the arguments. The the standard ML function 'null' may be
applied to lists of any type (list of integer, list of string, ...),
but it always has the same meaning and implementation. I believe this
style of polymorphism is called 'parametric polymorphism', perhaps
because it is the function parameter that can have different types.

Overloading is a notational device that permits a programmer to use
the same notation to mean one of several different things (i.e.,
different semantics and implementation) depending on the types of
arguments (and possibly also results). For example, in Ada it is
possible to define an overloaded function One (I *will* get the
notation wrong; I haven't looked at Ada for years):