← Back to context

Comment by adrian_b

23 days ago

Overloading can be easily abused, but the very complicated expressions that can appear in programs for scientific/technical computing are immensely more readable when using operator overloading like in C++ instead of using named functions, like in languages that forbid operator overloading, e.g. Java.

In scientific/technical computing you have frequently, even in the same expression, dozens of different kinds of additions, multiplications, divisions, etc., between scalars, vectors, matrices, tensors, complex numbers, various kinds of physical quantities, and so on. Without operator overloading the expressions can become huge, extending on a great number of program lines and they can be very difficult to understand.

Also, Pascal's method of using a single kind of statement brackets, i.e. "begin" and "end" (renamed in C as "{" and "}"), which has been inherited from Algol 60, is wrong for program readability.

The right method has been introduced by Algol 68 and it was inherited by languages like Ada. In such languages there are several kinds of statement brackets, like in the UNIX shell, where "if" and "fi" are brackets for conditional statements, "do" and "done" are brackets for loops and "case" and "esac" are brackets for selection statements. This is much more readable, especially when there is a big loop that can not be seen in a single page of code, so you see only its end, which is also the end of many other kinds of program structures, like nested loops, conditional statements or selection statements.

To get the same readability in languages like Pascal and C, you can add comments to the final braces or "end" of the program structures, but this is much more cumbersome than in a language with several kinds of statement brackets, where the bracket pairs will normally be added automatically by your text editor.

It's precisely when "you have frequently, even in the same expression, dozens of different kinds of additions, multiplications, divisions, etc., between scalars, vectors, matrices, tensors, complex numbers, various kinds of physical quantities, and so on" that operator overloading should be driven by custom syntax macros. (E.g. in a Rust-like language you might define math_expr!(...), float_expr!(...), matrix_expr!(...) etc. syntax macros, each with its own special semantics for operator symbols.) That way a program can directly express the variety of overloading that's relevant in any given context, as opposed to relying on fragile hacks like special __add__ and __mul__ "traits" that are dispatched in a type-dependent way.