Operator precedence and unary minus

classic Classic list List threaded Threaded
15 messages Options
Reply | Threaded
Open this post in threaded view
|

Operator precedence and unary minus

Egor Skriptunoff-2
Hi!

In most programming languages (and in Lua too) unary minus has higher priority than group of multiplicative operators ( * / % ).
It usually doesn't cause any problems due to "commutativity" between negation and any multiplicative operator in most programming languages:
(-a) * b == - (a*b)
(-a) / b == - (a/b)
(-a) % b == - (a % b)
As you can see, precedence of unary minus actually doesn't matter when only basic arithmetic operators are involved ( + - * / % ).
We can write (...-a%b) without worrying about precedence of binary / unary minus.

But Lua is special.
Lua has mathematically correct modulo operator (and that's great !).
The problem arises because in Lua negation operator is "not commutative" with modulo:
(-a) % b ~= - (a%b)

That's why in Lua we have an unpleasant surprise:
- a%m - b%n ~= - b%n - a%m
It's looks very weird.
That should be an equality as in all other programming languages.

I think it would be good to lower the priority of unary minus in Lua.
For example, unary minus may have the same priority as binary minus.
What do you think about it?

BTW, the same problem exists for // operator.

-- Egor
Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Coda Highland
On Mon, May 21, 2018 at 3:47 PM, Egor Skriptunoff
<[hidden email]> wrote:

> Hi!
>
> In most programming languages (and in Lua too) unary minus has higher
> priority than group of multiplicative operators ( * / % ).
> It usually doesn't cause any problems due to "commutativity" between
> negation and any multiplicative operator in most programming languages:
> (-a) * b == - (a*b)
> (-a) / b == - (a/b)
> (-a) % b == - (a % b)
> As you can see, precedence of unary minus actually doesn't matter when only
> basic arithmetic operators are involved ( + - * / % ).
> We can write (...-a%b) without worrying about precedence of binary / unary
> minus.
>
> But Lua is special.
> Lua has mathematically correct modulo operator (and that's great !).
> The problem arises because in Lua negation operator is "not commutative"
> with modulo:
> (-a) % b ~= - (a%b)
>
> That's why in Lua we have an unpleasant surprise:
> - a%m - b%n ~= - b%n - a%m
> It's looks very weird.
> That should be an equality as in all other programming languages.
>
> I think it would be good to lower the priority of unary minus in Lua.
> For example, unary minus may have the same priority as binary minus.
> What do you think about it?
>
> BTW, the same problem exists for // operator.
>
> -- Egor

That kind of subtle semantic change sounds like a terrible idea. Sure,
mathematically it would be nice, but it could break existing code in a
way that could be very subtle. The benefit doesn't seem to be worth
the risk.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Dirk Laurie-2
In reply to this post by Egor Skriptunoff-2
2018-05-21 22:47 GMT+02:00 Egor Skriptunoff <[hidden email]>:

> That's why in Lua we have an unpleasant surprise:
> - a%m - b%n ~= - b%n - a%m
> It's looks very weird.
> That should be an equality as in all other programming languages.

All? Let's try APL.

      a←10 ⋄ b←20 ⋄ m←3 ⋄ n←4
      -a|m-b|n
¯9
      -b|n-a|m
¯1

Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Tim Hill


> On May 21, 2018, at 2:45 PM, Dirk Laurie <[hidden email]> wrote:
>
> 2018-05-21 22:47 GMT+02:00 Egor Skriptunoff <[hidden email]>:
>
>> That's why in Lua we have an unpleasant surprise:
>> - a%m - b%n ~= - b%n - a%m
>> It's looks very weird.
>> That should be an equality as in all other programming languages.
>
> All? Let's try APL.
>
>      a←10 ⋄ b←20 ⋄ m←3 ⋄ n←4
>      -a|m-b|n
> ¯9
>      -b|n-a|m
> ¯1
>

All SANE languages? :)

—Tim


Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Tim Hill
In reply to this post by Egor Skriptunoff-2


> On May 21, 2018, at 1:47 PM, Egor Skriptunoff <[hidden email]> wrote:
>
> Hi!
>
> In most programming languages (and in Lua too) unary minus has higher priority than group of multiplicative operators ( * / % ).
> It usually doesn't cause any problems due to "commutativity" between negation and any multiplicative operator in most programming languages:
> (-a) * b == - (a*b)
> (-a) / b == - (a/b)
> (-a) % b == - (a % b)
> As you can see, precedence of unary minus actually doesn't matter when only basic arithmetic operators are involved ( + - * / % ).
> We can write (...-a%b) without worrying about precedence of binary / unary minus.
>
> But Lua is special.
> Lua has mathematically correct modulo operator (and that's great !).
> The problem arises because in Lua negation operator is "not commutative" with modulo:
> (-a) % b ~= - (a%b)
>
> That's why in Lua we have an unpleasant surprise:
> - a%m - b%n ~= - b%n - a%m
> It's looks very weird.
> That should be an equality as in all other programming languages.
>
> I think it would be good to lower the priority of unary minus in Lua.
> For example, unary minus may have the same priority as binary minus.
> What do you think about it?
>
> BTW, the same problem exists for // operator.
>
> -- Egor

You really dont want to alter precedence if unary minus. As others have noted, it’s going to break LOTS of code. It also introduces very strange effects with literal negative numbers, especially when you have metamethods involved.

—Tim


Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

dyngeccetor8
In reply to this post by Egor Skriptunoff-2
On 05/21/2018 11:47 PM, Egor Skriptunoff wrote:
> The problem arises because in Lua negation operator is "not commutative"
> with modulo:
> (-a) % b ~= - (a%b)
>
> That's why in Lua we have an unpleasant surprise:
> - a%m - b%n ~= - b%n - a%m> It's looks very weird.
> That should be an equality as in all other programming languages.

Probably in that languages negation operator _is_ commutative:

-(a % b) == (-a) % b

Lua 5.3 has four unary operators: "#", "~", "-", "not".
Lowering priority of "-" looks inconsistent.
Lowering priority of all unary operators hurts more than cures.

-- Martin

Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Albert Chan
In reply to this post by Egor Skriptunoff-2

> - a%m - b%n ~= - b%n - a%m
> It's looks very weird

Remove space between unary minus and variable,
and some parenthesis, it does not look weird

(-a % m) - (b % n) ~= (-b % n) - (a % n)

You can do the same trick to make any expression weird:

a  *  b+c  *  d+e / a  ^  3*c

> I think it would be good to lower the priority of unary minus in Lua.
> For example, unary minus may have the same priority as binary minus.
>
> -- Egor

Even if the idea is sound, it is too late to fix precedence

Anyway, how can it parse simple x / -y ?


Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Tim Hill


> On May 21, 2018, at 3:32 PM, Albert Chan <[hidden email]> wrote:
>
>
>> - a%m - b%n ~= - b%n - a%m
>> It's looks very weird
>
> Remove space between unary minus and variable,
> and some parenthesis, it does not look weird
>
> (-a % m) - (b % n) ~= (-b % n) - (a % n)
>
> You can do the same trick to make any expression weird:
>
> a  *  b+c  *  d+e / a  ^  3*c
>
>> I think it would be good to lower the priority of unary minus in Lua.
>> For example, unary minus may have the same priority as binary minus.
>>
>> -- Egor
>
> Even if the idea is sound, it is too late to fix precedence
>
> Anyway, how can it parse simple x / -y ?
>
>

You also need to be careful with literals and metatables. Consider:

-a * b
-10 * b

The same result? But what if b has a __mul metamethod?

—Tim


Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Dirk Laurie-2
In reply to this post by Tim Hill
2018-05-21 23:48 GMT+02:00 Tim Hill <[hidden email]>:

>
>
>> On May 21, 2018, at 2:45 PM, Dirk Laurie <[hidden email]> wrote:
>>
>> 2018-05-21 22:47 GMT+02:00 Egor Skriptunoff <[hidden email]>:
>>
>>> That's why in Lua we have an unpleasant surprise:
>>> - a%m - b%n ~= - b%n - a%m
>>> It's looks very weird.
>>> That should be an equality as in all other programming languages.
>>
>> All? Let's try APL.
>>
>>      a←10 ⋄ b←20 ⋄ m←3 ⋄ n←4
>>      -a|m-b|n
>> ¯9
>>      -b|n-a|m
>> ¯1
>>
>
> All SANE languages? :)

APL is the only sane language :-) No precedence. Very little syntax,

Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Sean Conner
In reply to this post by Tim Hill
It was thus said that the Great Tim Hill once stated:
>
> You also need to be careful with literals and metatables. Consider:
>
> -a * b
> -10 * b
>
> The same result? But what if b has a __mul metamethod?
>
> —Tim

  -10 * b and b has a __mul metamethod equals -Tim?

  -spc (Tongue firmly planted in cheek)

Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Tim Hill


> On May 21, 2018, at 4:02 PM, Sean Conner <[hidden email]> wrote:
>
> It was thus said that the Great Tim Hill once stated:
>>
>> You also need to be careful with literals and metatables. Consider:
>>
>> -a * b
>> -10 * b
>>
>> The same result? But what if b has a __mul metamethod?
>>
>> —Tim
>
>  -10 * b and b has a __mul metamethod equals -Tim?
>
>  -spc (Tongue firmly planted in cheek)
>

Yes yes but you get my point, even with tongue in cheek. In the first case, the return value of the metamethod is negated (according to the proposal), in the second it is not. Something NOT apparent from a casual glance at the code, and quite horrible imho.

—Tim


Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Egor Skriptunoff-2
In reply to this post by dyngeccetor8
On Tue, May 22, 2018 at 1:57 AM, dyngeccetor8 wrote:

Lua 5.3 has four unary operators: "#", "~", "-", "not".
Lowering priority of "-" looks inconsistent.
Lowering priority of all unary operators hurts more than cures.


Unary operators are very different.
Why do you want all unary operators to have the same priority?
I see no point in it.
Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Coda Highland
On Mon, May 21, 2018 at 11:52 PM, Egor Skriptunoff
<[hidden email]> wrote:

> On Tue, May 22, 2018 at 1:57 AM, dyngeccetor8 wrote:
>>
>>
>> Lua 5.3 has four unary operators: "#", "~", "-", "not".
>> Lowering priority of "-" looks inconsistent.
>> Lowering priority of all unary operators hurts more than cures.
>>
>
> Unary operators are very different.
> Why do you want all unary operators to have the same priority?
> I see no point in it.

Because three of those four are negation operators and SHOULD behave
the same way? I wouldn't complain if # had a different precedence than
the rest, but the others should be as consistent as possible.

/s/ Adam

Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

dyngeccetor8
In reply to this post by Egor Skriptunoff-2
On 05/22/2018 07:52 AM, Egor Skriptunoff wrote:

> On Tue, May 22, 2018 at 1:57 AM, dyngeccetor8 wrote:
>
>>
>> Lua 5.3 has four unary operators: "#", "~", "-", "not".
>> Lowering priority of "-" looks inconsistent.
>> Lowering priority of all unary operators hurts more than cures.
>>
>>
> Unary operators are very different.
> Why do you want all unary operators to have the same priority?
> I see no point in it.
>

I find it easy to state that all unary operators have the same
priority than to explain why unary minus is so different.

By the way, "~ - 1" is "0" now. After you change it'll become
"- ~ 1" which is "2".

Your well explained case with non-symmetric "mod" is one of
features of languages which have to be kept in mind.
Just like platinum question about "broken" "#" operator.

--

I believe all unary operators should have highest priority.

Current operator priorities:

  3.4.8 – Precedence

  Operator precedence in Lua follows the table below, from lower to higher priority:

       or
       and
       <     >     <=    >=    ~=    ==
       |
       ~
       &
       <<    >>
       ..
       +     -
       *     /     //    %
       unary operators (not   #     -     ~)
       ^

  -- https://www.lua.org/manual/5.3/manual.html

So "- 2 ^ 2" is "-4.0" and to square length of string "s" you
have to write "(# s) ^ 2".

-- Martin

Reply | Threaded
Open this post in threaded view
|

Re: Operator precedence and unary minus

Lorenzo Donati-3
In reply to this post by Tim Hill
On 21/05/2018 23:48, Tim Hill wrote:
>
>

[snip]

>>
>>      a←10 ⋄ b←20 ⋄ m←3 ⋄ n←4
>>      -a|m-b|n
>> ¯9
>>      -b|n-a|m
>> ¯1
>>
>
> All SANE languages? :)
>
Mmmh... language?

My mail client must be broken, I only see line noise.

;-)


> —Tim
>
>
>