Compare (fake Go-with-Swift-generics syntax):
func Distance<N>(x N, y N) N where N Number {
return x.Mul(x).Add(y.Mul(y)).Sqrt()
}
Versus: func Distance<N>(x N, y N) N where N Number {
return Sqrt(x * x + y * y)
}
If your reaction is "well, Distance doesn't look too bad like that", I can replace it with matrix multiplication or point-inside-triangle testing. Not having overloading quickly fails to scale.(It's totally fine for a language to be not interested in that domain. But that doesn't mean operator overloading is bad. Overloaded operators are essential for some domains.)
Many times you don't care for the (costly) square root, so a distance-squared function can be useful.
Multiplying x by itself ("squaring") can also be a useful function that is used a lot.
(defun distance (x y) (sqrt (distance-squared x y)))
(defun distance-squared (x y) (+ (square x) (square y)))
(defun square (x) (* x x))
In the same way that we can decompose our code, we can also decompose
the concept of "operator overloading": it gives you is the ability to
use one-letter (1), fixed-arity and precedence-following (P), infix
(I), operators for your own or someone else's operations (G).In languages that support 1PI properties, you'd often overlook such decompositions because it's quick and easy to write sqrt(x * x + y * y). To read it, also, but then you find yourself doing more and more complex calculations in-line. Reading suffers. You may end up with something that's worse than the corresponding code in a language that encourages defining small functions instead. (Lisp, of course, lets you use any combination of these properties, but the latter style is the one normally used.)
Yes, this is a Go thread... but I'll leave it here anyway.
edit: rereading the earlier comments, this may be orthogonal to the GP's claim that operator overloading is crucial for generics. Ooops. :)
I think you may have the causality swapped here; I think <algorithm> looks the way it does because they limited themselves to things that could be easily expressed with operators --- for a long time, to the detriment of the language; see: STL associative containers, operator<, and the longstanding lack of a standard hash table.
Josuttis claims that hash tables didn't make it in C++98 due to lack of time.