Operators priority when designing a language?

Community Forums/General Help/Operators priority when designing a language?

ziggy(Posted 2012) [#1]
The POW operator is very weird.
I'm right to assume that the unnary - operator should have less preference than the POW operator, when it is placed at the left of the operator, and have more preference than it when it is at the right?

I mean:
-2^2 should be -4
2^-2 should be 0.25
Does this lookd right? I'm finding it a bit weird that the operators execution prefence depends on possition, but this is what looks much more natural to me. Any ideas? I'm doing it this properly?

Also, currently I'm processing operators in this order:
( ) parenthesis
+, -, ~ unnary when are part of an exponent on a POW operation
^ POW
+, -, ~ unnary when are NOT part of an exponent on a POW operation
*, /, % Multiplication, division and modulus, in order from left to right
+, - Addition and substraction in order from left to right
++ String concatenation in order from left to right
& Bitwise AND operator
|, ~ Bitwise or and xor operators
shl, shr Butwise shift operators
=, >, <, >=, <=, <> Comparison operators
And Logical AND operator
Or Logical OR operator

Does this order makes sense? I'm doing it based on my experience using compilers, so I always have the feeling that I'm missing something...

Last edited 2012

Last edited 2012

Last edited 2012


Yasha(Posted 2012) [#2]
Does this order makes sense?


No, for one very simple reason:

Each operator should appear in the list once and only once.

By making unary operators apply to the whole of a POW expression, you are creating an unnecessary inconsistency, and increasing the complexity of the grammar, because they need to appear in the second position below it as well, and then you also need more contextual information to decide which way things should be parsed...

It would make a whole lot more sense to just leave them at the top (which is the only place where they can really be consistent), and have (- 2 ^ 2) = 4.

Also, consider the expanded versions. Which of these looks more awkward:

(- 2) ^ 2
- (2 ^ 2)

To me, the first one looks silly, and shouldn't appear unless the programmer has an unnatural love of parens, because the parens don't look like they're grouping anything. In the second, the parens are visually clearly fulfilling their usual role. Therefore the first one would be the one to make the implicit order of operations, so it doesn't have to ever be written out.


...of course, as always, order of operations is just a convention, not a mathematical law. If your language isn't directly based on another one, you can get away with changing it (conversely, if your language is based on e.g. C you should copy C, whether you think it's right or not, or people will have a touch time using it easily, because they will expect it to work in a different way).


xlsior(Posted 2012) [#3]
The windows calculator tells me that -2^2 is 4.
Blitzmax thinks it's 4.
Online-calculator.com thinks it's 4.

http://en.wikipedia.org/wiki/Order_of_operations


H&K(Posted 2012) [#4]
Also, currently I'm processing operators in this order:
( ) parenthesis
+, -, ~ unnary when are part of an exponent on a POW operation
^ POW
+, -, ~ unnary when are NOT part of an exponent on a POW operation

Even in your definition -2^2 is 4


ziggy(Posted 2012) [#5]
Ok in other words:
X = 2
Y = - X ^ 2
Are you sure you would expect Y to be 4 instead of -4 ?


Jesse(Posted 2012) [#6]
I believe theri is a bug in BMax as these 2 equations should produce the same result but they dont:
0-x^2
-x^2

the correct result should be the top one.

-2^2 should be 4 not negative 4 and is the same as (-2*-2)

Last edited 2012

Last edited 2012


Yasha(Posted 2012) [#7]
these 2 equations should produce the same result but they dont:


No, they shouldn't. They're completely different operations, as discussed above. 0 - x is a binary minus, which is of lower precedence than ^. - x is a unary minus, which is of higher precedence then ^. In BlitzMax this is not a bug, it is entirely as the Good Docs say.

The discussion is about whether it would be sensible to change this behaviour in Ziggy's language.

Incidentally, what is the language like/based on? Suggestions on this sort of topic should take into account what your design goals are, and who is supposed to use it.


So...
Are you sure you would expect Y to be 4 instead of -4 ?


...definitely. I would expect a good design-related reason for breaking convention. Otherwise, you're just changing the precedence rules users are expecting.


ziggy(Posted 2012) [#8]
I believe theri is a bug in BMax as these 2 equations should produce the same result but they dont
No it's not a bug, the first example, the - is a substraction, the second example the - is a unnary operator (negative of). The unnary operator has higher prefence on the calculation chain, so it is set before the POW happens, and the final result is possitive, while in the substraction sample, the POW happens before than the substraction, leaving a negative result.
I'm just seeing that BlitzMax does give higher priority to unnary operators always and if that has worked for this long, I supose it's the way to go

I would expect a good design-related reason for breaking convention
Of course. I was just thinking on some comments made by Floyd here: http://www.blitzmax.com/Community/posts.php?topic=97373#1130844
But, after making some tests, I do not think it was a good idea in the first place, so I think I'll leave unnary operators only at the first level, just after ( ).

Other than that, do you think the operators processing order is the one you would expect on a general purpose language?

The language I'm designing is just an interpreted basic-like language written in Monkey with the idea that it can then run in any kind of device. It's just a sort of research project, not a commercial one, and it is still in very early status (more info here: http://code.google.com/p/harpl-project/wiki/WhatsHarpl )

Last edited 2012


Jesse(Posted 2012) [#9]

No it's not a bug, the first example


I got that from Yasha and since I didn't know for sure and I wasn't convinced I looked it up:
http://en.wikipedia.org/wiki/Order_of_operations

He is right.

Last edited 2012


Yasha(Posted 2012) [#10]
Other than that, do you think the operators processing order is the one you would expect on a general purpose language?


Pretty much. Seems fairly conventional. You've got an unusual precedence for shift operators, but that seems to vary anyway (different between BlitzMax, Blitz3D, and C), so could be a non-issue.

I definitely like the choice to make string concatenation a distinct operation from addition. That might make things a little cleaner and eradicate some weird bugs for beginners... and it makes more logical sense.

Looks like a cool project.


Floyd(Posted 2012) [#11]

-2^2 should be -4
2^-2 should be 0.25


Both are correct.

The POW operator ^ should have higher precedence than unary minus. Thus -2^2 is -(2^2).

In the second example 2^-2 is 2^(-2). This is not because unary - suddenly has higher precedence. It is because there is no other possible interpretation.

^ has two operands so an expression must be of the form

op^op

Unary minus has one operand and an expression must be

-op

In the first example we must choose between (-2)^2 and -(2^2). We choose -(2^2) because ^ has higher precedence.

In the second example we get 2^(-2). It can't be anything else no matter what precedence we use.


ziggy(Posted 2012) [#12]
Looks like a cool project.

Thanks, we'll see where it ends...

Do you think using the ~ operator both for xor and for unary compliment is a good idea? (I really don't like using the same operator for 2 different things, except in cases like unary and binary operators, but in this case, I'm not sure it is a good idea.)


Yasha(Posted 2012) [#13]
This is not because unary - suddenly has higher precedence. It is because there is no other possible interpretation.


This is exactly why unary minus conventionally has higher precedence than ^. Because in your example, putting it on the right argument means it suddenly has higher precedence.

Your rule is flat-out inconsistent. It's arbitrarily changing the precedence of an operator based on the expression around it, which violates the whole point of operator precedence. Operators should appear once and only once in the table.

Do you think using the ~ operator both for xor and for unary compliment is a good idea?


It seems to work well enough for BlitzMax...

Your other option is to invent a new operator, or use a text operator (advise against, would introduce confusion with the logical operators). As far as I know the only other "standard" is to use ^, which you're already using for something more intuitive.


ziggy(Posted 2012) [#14]
I'll go for unary higher preference than ^ for the compiler, and maybe provide a POW function too, just to help preventing this confusion (lots of languages do it as a funtion too, so I supose it's also a good idea).


Floyd(Posted 2012) [#15]
This is exactly why unary minus conventionally has higher precedence than ^. Because in your example, putting it on the right argument means it suddenly has higher precedence.


My example was 2^-2 being evaluated as 2^(-2). That's not operator precedence. It's simply because the single operand of unary minus must be to the right of the - symbol.

What else could 2^-2 be? The only other choice is to do first ^ and then -, yielding -(2^2), which is obvious nonsense.


Floyd(Posted 2012) [#16]
...and maybe provide a POW function too...

That's a reasonable workaround, but I've never liked it. I prefer mathematical expressions to look as much like handwritten work as possible.
x² + y²                would be ideal
x^2 + y^2              is acceptable
pow(x,2) + pow(y,2)    well, I can live with it if necessary



Yasha(Posted 2012) [#17]
The fact that the alternative is obvious nonsense is why unary minus has a higher precedence; there's no other alternative.

A system which follows your proposed rule could be entirely legitimate, but it wouldn't be a precedence-based system, and mixing it with operator precedence wouldn't make any sense. If you use operator precedence, -2^2 has to equal 4, or the system is inconsistent. If unary minus has a lower precedence than ^, you'd better get to work finding a way to make that ^ come first in 2^-2.

...which is why every other precedence-based notation follows this rule.

Last edited 2012


H&K(Posted 2012) [#18]
OK
Its because 2^-2 doesn't exist

Its just that on a keyboard its a pain to type 1/2^2 or 1/(2^2) and it be obvious what belongs to which.
So the negative POW is taken to mean one over the positive power answer


Floyd(Posted 2012) [#19]
...which is why every other precedence-based notation follows this rule.

That is certainly not true. I've seen both ways, but prefer exponentiation to have higher precedence than unary minus.

That's the way it is with my TI calculator, or with Visual Basic.

I just checked -2^2 on the calculator. It evaluates as -4.

By the way, the calculator makes it's own life easier by having separate symbols for unary minus and subtractions, which I don't really like, but can tolerate.

Last edited 2012


Shortwind(Posted 2012) [#20]
A review of how negative numbers actually work would be in order here:

http://mathforum.org/library/drmath/view/57866.html


ziggy(Posted 2012) [#21]
We know how do they work, it is a mather of how the compiler should organize its calculation. As instance; BlitzMax, VB.net and C do evaluate negative signs and exponents differently, so not really 100% clear.
For my small compiler, I'm going to priorize unary operators over any other operator.