I'm a bit skeptical. When used right; operator overloading is an elegant extension of a language. But all too often i feel they are a too powerful abstraction tool that can be abused to make a library utterly incomprehensible and make intuition about language syntax unreliable. I see this in c++ at times.
In particular if you've looked at linear algebra libraries that have two or three different multiplication operators (cross, dot, bitwise), if they commit to use functions from the start they end up faar more readable than any attempt to abuse operator overloading.
I prefer;
- DSL (domain specific language, especially for symbolic solving such as mathematica)
- Strings (That's just a DSL hiding in a parse() function, that can be called from a different language. Write the code as if its a DSL, but without pulling in a new tech stack)
- Functions, but preferable in a chain-able style. sym("a").add(1).eq(sym("b")).solve() is better than solve(eq(add(1,a),b))
I have seen operator overloading done right... but I've also cursed loudly at it done badly.
Rust in particular use up most symbols for other things (borrow checker takes alot of them, and "==" is forced to be consistent) so you end up with only "+ - * /" as overload-able. "+" and "-" being the least abused from my experience perhaps makes that a good compromise.
I would say that for the specific use-case of a modeling layer for something like constraint programming, SMT, or MIP, full operator overloading is superior. I've written such layers in many languages and used them in even more languages, and it really does help a _lot_ to have the standard mathematical expressions. All the other alternatives become way to cumbersome to write effective models with in my experience.
Is it worth having operator overloading in a language or not? That is a different question. People do bad things with every feature, including operator overloading. I'm slightly in favor of it, but I'm not a fan of using it for anything other than either immediate arithmetic or creating expressions trees representing arithmetic.
In particular if you've looked at linear algebra libraries that have two or three different multiplication operators (cross, dot, bitwise), if they commit to use functions from the start they end up faar more readable than any attempt to abuse operator overloading.
I prefer;
- DSL (domain specific language, especially for symbolic solving such as mathematica)
- Strings (That's just a DSL hiding in a parse() function, that can be called from a different language. Write the code as if its a DSL, but without pulling in a new tech stack)
- Functions, but preferable in a chain-able style. sym("a").add(1).eq(sym("b")).solve() is better than solve(eq(add(1,a),b))
I have seen operator overloading done right... but I've also cursed loudly at it done badly.
Rust in particular use up most symbols for other things (borrow checker takes alot of them, and "==" is forced to be consistent) so you end up with only "+ - * /" as overload-able. "+" and "-" being the least abused from my experience perhaps makes that a good compromise.