Thread overview
Precedences of unary minus and dot operators
Nov 08, 2013
bearophile
Nov 08, 2013
Daniel Kozak
Nov 08, 2013
simendsjo
Nov 08, 2013
Dicebot
Nov 08, 2013
bearophile
Nov 08, 2013
deed
Nov 08, 2013
Artur Skawina
Nov 08, 2013
inout
November 08, 2013
This is something that has come out of a thread I have opened in D.learn.

In the thread qznc has answered me:

> Operator precedence of "." is higher than unary minus.


That's right:


double foo(in double x) {
    assert (x >= 0);
    return x;
}
void main() {
    assert(-1.foo == -1);
}


Is this a good design of the operator precedences? Is this worth changing/fixing?

Bye,
bearophile
November 08, 2013
On Friday, 8 November 2013 at 12:49:38 UTC, bearophile wrote:
> This is something that has come out of a thread I have opened in D.learn.
>
> In the thread qznc has answered me:
>
>> Operator precedence of "." is higher than unary minus.
>
>
> That's right:
>
>
> double foo(in double x) {
>     assert (x >= 0);
>     return x;
> }
> void main() {
>     assert(-1.foo == -1);
> }
>
>
> Is this a good design of the operator precedences? Is this worth changing/fixing?
>
> Bye,
> bearophile

From my POV this is good design. When I see:
assert(-1.foo == -1);
Is same for me as:
assert(-foo(1) == -1);

November 08, 2013
On Friday, 8 November 2013 at 12:53:24 UTC, Daniel Kozak wrote:
> On Friday, 8 November 2013 at 12:49:38 UTC, bearophile wrote:
>> This is something that has come out of a thread I have opened in D.learn.
>>
>> In the thread qznc has answered me:
>>
>>> Operator precedence of "." is higher than unary minus.
>>
>>
>> That's right:
>>
>>
>> double foo(in double x) {
>>    assert (x >= 0);
>>    return x;
>> }
>> void main() {
>>    assert(-1.foo == -1);
>> }
>>
>>
>> Is this a good design of the operator precedences? Is this worth changing/fixing?
>>
>> Bye,
>> bearophile
>
> From my POV this is good design. When I see:
> assert(-1.foo == -1);
> Is same for me as:
> assert(-foo(1) == -1);

If I saw this, I would have to test it to be sure.. I feel it's in the same area as several post/pre increment/decrement in the same line.
November 08, 2013
On Friday, 8 November 2013 at 12:49:38 UTC, bearophile wrote:
> Is this a good design of the operator precedences? Is this worth changing/fixing?
>
> Bye,
> bearophile

Yes it is expected and reasonable to me. Otherwise you'd need brackets for every expression like this: `-aggregate.field`
November 08, 2013
Dicebot:

> Yes it is expected and reasonable to me. Otherwise you'd need brackets for every expression like this: `-aggregate.field`

For me it's weird... :-)

Thank you for the answers.

Bye,
bearophile
November 08, 2013
> For me it's weird... :-)

import std.math;

assert (-3.abs == 0 - 3.abs);
assert ((-3).abs == (0 - 3).abs);

Makes sense..
November 08, 2013
On 11/08/13 14:59, bearophile wrote:
> Dicebot:
> 
>> Yes it is expected and reasonable to me. Otherwise you'd need brackets for every expression like this: `-aggregate.field`
> 
> For me it's weird... :-)

The weirdness does not really come from the op precedence, but UFCS and
literals. Ie there's nothing weird with 'f(-3.14)', nor '-pi.f()'; it's
first when it's written like '-3.14.f()' that it becomes very unintuitive.
Somebody asked recently about D gotchas -- this is one, and it will cause bugs.
Most people will not start out with '(-3.14).f()'...

artur
November 08, 2013
On Friday, 8 November 2013 at 12:49:38 UTC, bearophile wrote:
> This is something that has come out of a thread I have opened in D.learn.
>
> In the thread qznc has answered me:
>
>> Operator precedence of "." is higher than unary minus.
>
>
> That's right:
>
>
> double foo(in double x) {
>     assert (x >= 0);
>     return x;
> }
> void main() {
>     assert(-1.foo == -1);
> }
>
>
> Is this a good design of the operator precedences? Is this worth changing/fixing?
>
> Bye,
> bearophile

struct Foo
{
    int value = 9;
};

struct Bar
{
    // implements unary minus
    int value = 9;
};

int squareRoot(Bar bar) { return sqrt(bar.value); }

int main() {
  Foo foo;
  writeln(-foo.value); // prints -9, by first getting the value and then negating it

  Bar bar;
  writeln(-bar.squareRoot); // for consistency, this should also call squareRoot first
  // otherwise, the order of operations would depend on whether the struct has opUnary implemented