As the title says, I find it useful to be able to overload operators. Is it possible to also change the way the operators are parsed by specifying the precedence and associativity of overridden operators?
- Anybody can ask a question
- Anybody can answer
- The best answers are voted up and rise to the top
No, you can't do that and that's a good thing. Operator overloading already has enough potential to make code unreadable without being able to change precedence or associativity.
If you even want to do that you are probably abusing operator overloading and should use normal functions instead.
No. Besides making code unreadable, it would make the language more ambiguous and deeply context-dependent because you would not be able to associate parameters with function calls until after you know all the operators available.
Consider the expression
This could be interpreted two different ways
With global precedence and associativity rules, the compiler can commit to the first interpretation during parse, but with overridable associativity/precedence, there's no way to figure out how to decompose tokens into function calls until you know all the available operator signatures.
This doesn't make the language impossible to parse (although there are more programs that have to be rejected as untypable) but it would make it slower to compile, and harder to read.
No. While it may at first sight seem to make sense, if you think a little more, it becomes muddy to the point that it's a bad idea.
First note that the language isn't defined by using a precedence grammar, but a more classic BNF. I'm not sure that the behavior of
But the major issue is that you are changing the priority and associativity of overloaded operators, not defining the priority and associativity of new operators used only for your types. Do you want your changes to be applicable for all uses, or just for your overload? You'll probably agree that the first option is a sure receipt for trouble. The other isn't much better. How to you know it's your overload which should be considered before doing overload resolution, which need parsing and thus associativity and priority to be known.
After reading some of the answers I think that, yes, it's time for me to look for down-votes.
Despite this well established fact, there is still people claiming that overloading operator makes the code unreadable, and hence you should not ... blah blah ... and them must not ... blah blah ... and allowing to change precedence.
I find these argumentation simply incoherent.
Operators are what makes entity to form expression that together defines an algebra. If an entity is not numeric, there is no need (I mean mathematical need) that such an algebra has to follow the same rule of natural numbers.
One of the reason that overloaded operators makes code hard to read is just because they are constrained to stay into the int semantic rules, even for things that has not integer semantics and hence don't need that same syntax.
The answer to the question is:
NO: you cannot change precedence because the language specification don't allow. Full stop.
And if you want to know why, you have to look at what the language is for.
C++ is already an complex language to parse and to translate.
By admitting "flex operators" (or even the definition of arbitrary infix-functions, like
All the "moral" aspect (don't do it because it hurts me) have nothing to do with the language and the operator abuse (I can even abuse of
C++ operator overloading was introduced to let scientist to define private algebraic types. It is normal for them to ask more flexibility id defining and using symbols.
The Java language was defined to standardize coding around OOP. And since not all programmers wannabees are also scientist reasercers, Java removed a number of feature that can make the language to deviate from the OOP paradigm it was philosophically designed around. And to motivate that to newbies, a dogmatic religion claiming "operator considered harmful", "global variables considered harmful" and so on was formalized ad deployed across schools.
And the bash against certain coding practices perfectly common in maths and science began just from there.
It is very simple to teach "no because is bad and makes you go to hell" instead to provide and compare rational ideas. And the result - 20 years later - is that if you do it, you really go to hell because all that religion believers (that nowadays are a huge amount of people) will make your life impossible.
And since Java became the first language newbies are exposed (and C++ eventually a second one) and its paradigms taught as dogmas to students, when those students become programmers they end up applying those "dogmas" to anything by an innate "extension".
After all no-one can give a rational reason abut his favorite football team. it just happen to be when you start follow it. There are no "technical reasons". Just passion (dogmas) and the stress to change (OOP methods forced even outside OOP context)
The reason you cannot change precedence is simply that the world retains that changing that dogma will cause too much stress to too much believers. But rationally speaking, there is no reason you can believe differently and makes you define a language with more freedom in usage.