Re: [Vala] Operator overloading



It seems useful to catalog the use-cases for operator overloading at
this point, since folks are missing the big picture by focusing on
only one or two:

--- Non-standard number representations ---
* Arbitrary-sized large integers
* Fractional (int/int) number represtations
* Base-10 floats for rounding issues
* Arbitrary-precision floating-point numbers
* 16-bit floats for OpenGL textures
These types would implement the four basic operators (+ - * /) as well
as modulo (%) for the integer types. Xavier Bestel says, "Math
operators should be limited to
purely math operations, on integers and reals." Well, Xavier, these
*are* integers and reals, and they want operator overloading.

--- Complex numbers ---
Like the real numbers, these numbers have well-defined versions of the
four basic operators (+ - * /). There is no ambiguity or lack of
clarity when someone says "complex1 + complex2" or "complex1 /
complex2". Many programming languages even have complex numbers as a
built-in type, including C99.

--- Quaternions ---
Quaternions are complex numbers generalized into four dimensions. As
with complex numbers, all four basic operators  (+ - * /) are
well-defined. Quaternions are used to represent rotations in 3D, among
other things.

--- Vectors ---
Vectors can come in fixed sizes like <x, y> to <x, y, z, z>, or they
may be arbitrarily sized. Depending on the application, vectors can be
represented with integers, floats, or doubles. In every case, the +
and - operators perform member-wise addition, and the * and /
operators perform scaling. Vectors also support other operations like
the dot product and cross product, but those should be implemented as
named functions as Frederik says earlier.

--- Matrices ---
Like vectors, matrices come in all sizes and types. Like vectors, the
+ and - operators operate member-wise, while the * and / operators
perform scalar multiplication. In addition, matrices define a *
operator that works on any two properly-sized matrices. The other
matrix operations like transpose and inverse would be named functions.
---

These are the applications I can think of, and I am sure there are
others. Each of these use-cases is a mathematical object, and the
operators that apply to these objects are well-established by
mathematical convention. Any programmer using these entities already
has the mathematical background to know how the operators should
behave. If not, they can always read the documentation. Named
functions, on the other hand, make reading documentation mandatory. Is
the member-wise addition function called "plus," "add," "add_to," or
what? Which of these functions modifies the original object, and which
does not? With operator overloading, the answer is simply "+" or "+=".
Isn't saving a trip to the documentation the nature of clear,
self-explanatory code?

I hear a lot of strong terms like "nightmarish" and "horror story" in
relation to operator overloading, but not a lot of concrete examples
to back them up. I agree that using << for IO is ugly, but that is
hardly justification for eliminating the entire feature. I suspect the
problem isn't operator overloading itself, but C++'s excessively
flexible nature. A locked-down implementation that supports only the
basic math operators (+ -  * / %), forces those operators to be
"const" to eliminate side effects, and forces the assignment operators
(+= -= *= /= %=) to behave predictably would fully support the use
cases above and would not leave much room for "nightmarish horror
stories". This isn't C++, where you can overload the [] or ->
operators to shoot yourself in the foot.

-William Swanson



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]