May 24, 2015
On 25 May 2015 00:20, "Andrei Alexandrescu via Digitalmars-d" < digitalmars-d@puremagic.com> wrote:
>
> On 5/24/15 1:29 PM, Timon Gehr wrote:
>>
>> BTW, the documentation contradicts itself on evaluation order: http://dlang.org/expression.html
>
>
> This comes up once in a while. We should stick with left to right through
and through. It's a "simple" matter of getting somebody on the compiler team to find the time for it. -- Andrei
>

I find it is not as clear cut as that.  In gdc, there is a compiler flag that tells the optimizer to honour left to right evaluation, and because of both what you say and the agreement of others, it seems natural to have this turned on by default.

However, this has an interesting side effect with operations with side effects.  Ie: foo += bar() could either produce expected or surprising results.

Hint, the LTR order - foo = foo + bar() - gives the most surprise in my
experience from users.


May 24, 2015
On 05/25/2015 12:15 AM, Andrei Alexandrescu wrote:
> On 5/24/15 1:29 PM, Timon Gehr wrote:
>> BTW, the documentation contradicts itself on evaluation order:
>> http://dlang.org/expression.html
>
> This comes up once in a while. We should stick with left to right
> through and through. It's a "simple" matter of getting somebody on the
> compiler team to find the time for it. -- Andrei
>

https://github.com/D-Programming-Language/dlang.org/pull/999
May 24, 2015
On 05/25/2015 12:36 AM, Iain Buclaw via Digitalmars-d wrote:
>
>  > This comes up once in a while. We should stick with left to right
> through and through. It's a "simple" matter of getting somebody on the
> compiler team to find the time for it. -- Andrei
>  >
>
> I find it is not as clear cut as that.  In gdc, there is a compiler flag
> that tells the optimizer to honour left to right evaluation, and because
> of both what you say and the agreement of others, it seems natural to
> have this turned on by default.
>
> However, this has an interesting side effect with operations with side
> effects.  Ie: foo += bar() could either produce expected or surprising
> results.
>
> Hint, the LTR order - foo = foo + bar() - gives the most surprise in my
> experience from users.
>

I think I still don't get it. What is the surprise? That bar() is evaluated before the value is written to foo?
May 24, 2015
On 5/24/15 3:36 PM, Iain Buclaw via Digitalmars-d wrote:
> On 25 May 2015 00:20, "Andrei Alexandrescu via Digitalmars-d"
> <digitalmars-d@puremagic.com <mailto:digitalmars-d@puremagic.com>> wrote:
>  >
>  > On 5/24/15 1:29 PM, Timon Gehr wrote:
>  >>
>  >> BTW, the documentation contradicts itself on evaluation order:
>  >> http://dlang.org/expression.html
>  >
>  >
>  > This comes up once in a while. We should stick with left to right
> through and through. It's a "simple" matter of getting somebody on the
> compiler team to find the time for it. -- Andrei
>  >
>
> I find it is not as clear cut as that.  In gdc, there is a compiler flag
> that tells the optimizer to honour left to right evaluation, and because
> of both what you say and the agreement of others, it seems natural to
> have this turned on by default.

Even better - the front end could force the sequencing.

> However, this has an interesting side effect with operations with side
> effects.  Ie: foo += bar() could either produce expected or surprising
> results.
>
> Hint, the LTR order - foo = foo + bar() - gives the most surprise in my
> experience from users.

I think LTR is the most sensible in all cases. -- Andrei

May 25, 2015
On 05/25/2015 01:49 AM, Andrei Alexandrescu wrote:
>
> I think LTR is the most sensible in all cases. -- Andrei

It is also what Java and C# do.
May 25, 2015
On 25 May 2015 01:10, "Timon Gehr via Digitalmars-d" < digitalmars-d@puremagic.com> wrote:
>
> On 05/25/2015 12:36 AM, Iain Buclaw via Digitalmars-d wrote:
>>
>>
>>  > This comes up once in a while. We should stick with left to right
>> through and through. It's a "simple" matter of getting somebody on the
>> compiler team to find the time for it. -- Andrei
>>  >
>>
>> I find it is not as clear cut as that.  In gdc, there is a compiler flag that tells the optimizer to honour left to right evaluation, and because of both what you say and the agreement of others, it seems natural to have this turned on by default.
>>
>> However, this has an interesting side effect with operations with side effects.  Ie: foo += bar() could either produce expected or surprising results.
>>
>> Hint, the LTR order - foo = foo + bar() - gives the most surprise in my
>> experience from users.
>>
>
> I think I still don't get it. What is the surprise? That bar() is
evaluated before the value is written to foo?

That foo is cached before bar() is evaluated.

The context here involves concurrency where bar() calls yield and makes changes to foo before returning to assign the updated results.


May 25, 2015
On Sun, 24 May 2015 19:30:52 +0000, kinke wrote:

> So for the 2nd assignment's left-hand-side, the index is evaluated before evaluating the container! Please don't tell me that's by design. :>

it is. at least this is what i was told when i faced the similar issue. "WONTIFX, STFU".

May 25, 2015
On Monday, 25 May 2015 at 07:33:49 UTC, ketmar wrote:
> On Sun, 24 May 2015 19:30:52 +0000, kinke wrote:
>
>> So for the 2nd assignment's left-hand-side, the index is evaluated
>> before evaluating the container! Please don't tell me that's by design.
>> :>
>
> it is. at least this is what i was told when i faced the similar issue.
> "WONTIFX, STFU".

To be fair, the example that the OP gave is almost the same thing as

foo(++i, ++i);

whereas what you came up with had a lot more layers to it, with whole chains of function calls affecting each other. With the kind of example you came up with, even with defining the evaluation as strictly left-to-right, you would _still_ run into screwy problems with stuff easily being mutated in a different order than you expected.

Defining the order of evaluation as being strictly left-to-right will avoid some of the common bugs cause by folks foolishly doing something like

foo(++i, ++i);

but the reality of the matter is, if you start doing stuff like mutating the arguments inside of the function inside of the function when the same arguments are being passed to other functions in the same expression, you _will_ have weird and unexpected stuff happening. It might be completely well-defined and consistent, but it may not be what you expect, and even if it is, a slight change to the code could change the order. So, the kind of stuff that you're complaining about not being able to do really shouldn't be done regardless of how well-defined the order of evaluation is. It's just begging for trouble.

- Jonathan M Davis
May 25, 2015
On Monday, 25 May 2015 at 08:00:15 UTC, Jonathan M Davis wrote:
> it is, a slight change to the code could change the order. So, the kind of stuff that you're complaining about not being able to do really shouldn't be done regardless of how well-defined the order of evaluation is. It's just begging for trouble.

The the compiler should complain about it...
May 25, 2015
On Monday, 25 May 2015 at 08:00:15 UTC, Jonathan M Davis wrote:
> It might be completely well-defined and consistent, but it may not be what you expect, and even if it is, a slight change to the code could change the order.

If the behavior isn't what I expect (and I don't think that's often case for left-to-right order), then the language should force me to express the intention differently. If it's not well-defined, I may not be aware of such issues until I use a different compiler. Allowing implementation-dependent evaluation order is just begging for additional bugs and portability issues.

Another example:

b = 0;
((++b *= 5) *= 2) += ++b * (b -= 6);

DMD yields b=60, LDC the intuitively correct b=65. If it's well defined, one may argue about the form of such a statement, but it's not silly code with different results depending on the used D compiler anymore.

+1 for Timon's PR being merged asap.