March 31, 2015
On 3/30/15 11:34 PM, deadalnix wrote:
> On Tuesday, 31 March 2015 at 06:20:22 UTC, Andrei Alexandrescu wrote:
>> On 3/30/15 8:49 PM, deadalnix wrote:
>>> On Tuesday, 31 March 2015 at 01:01:24 UTC, Andrei Alexandrescu wrote:
>>>> On 3/30/15 5:49 PM, deadalnix wrote:
>>>>> Why are you doing the replacement top/down rather than bottom up ?
>>>>
>>>> What would be the alternative? -- Andrei
>>>
>>> Doing the replacement bottom up :
>>>
>>> a = a++;
>>>
>>> a += { auto olda = a; a = a + 1; return olda; }();
>>>
>>> a = cast(typeof(a)) (a + { auto olda = a; a = a + 1; return olda; }());
>>
>> You need another lowering here because you evaluate a twice. Consider:
>>
>> import std.stdio;
>> int a;
>> ref int fun() { writeln("meh"); return a; }
>> void main() {
>>   fun() = i++;
>> }
>>
>
> Yeah, I had an int in mind. Make it
>
> {
>      aPtr = &a;
>      *aPtr = cast(typeof(a)) (*aPtr + { auto olda = *aPtr; *aPtr = a +
> 1; return olda; }());
>      return *aPtr;
> }()

So you propose the following lowering for e1 += e2:

e1 += e2

-\>

{
    auto __p = &(e1);
    *__p = cast(typeof(e1)) (*__p + e2);
}()

This looks contrived and it's no surprise is inconsistent with opOpAssign as you yourself noted. I prefer the lowering that identifies += to a function calls with two parameters:

e1 += e2

-\>

(ref a, b) { a = (cast(typeof(a)) (a + b); }(e1, e2)

>>> Other code transformation do not require a function call to take place,
>>> so why would this require one (which force eager evaluation of
>>> parameters) ?
>>
>> Everything needs to be evaluated (and only once).
>>
>>> That is also inconsistent with LTR evaluation.
>>
>> I don't see how.
>>
>
> a appear on the left of a++. a should be evaluated before a++. You
> propose that it isn't.

I see, thanks.

Guess we should change the spec no matter what. My money is on the lowering I mentioned.


Andrei

March 31, 2015
On Tuesday, 31 March 2015 at 06:50:16 UTC, Andrei Alexandrescu wrote:
> On 3/30/15 11:34 PM, deadalnix wrote:
>> On Tuesday, 31 March 2015 at 06:20:22 UTC, Andrei Alexandrescu wrote:
>>> On 3/30/15 8:49 PM, deadalnix wrote:
>>>> On Tuesday, 31 March 2015 at 01:01:24 UTC, Andrei Alexandrescu wrote:
>>>>> On 3/30/15 5:49 PM, deadalnix wrote:
>>>>>> Why are you doing the replacement top/down rather than bottom up ?
>>>>>
>>>>> What would be the alternative? -- Andrei
>>>>
>>>> Doing the replacement bottom up :
>>>>
>>>> a = a++;
>>>>
>>>> a += { auto olda = a; a = a + 1; return olda; }();
>>>>
>>>> a = cast(typeof(a)) (a + { auto olda = a; a = a + 1; return olda; }());
>>>
>>> You need another lowering here because you evaluate a twice. Consider:
>>>
>>> import std.stdio;
>>> int a;
>>> ref int fun() { writeln("meh"); return a; }
>>> void main() {
>>>  fun() = i++;
>>> }
>>>
>>
>> Yeah, I had an int in mind. Make it
>>
>> {
>>     aPtr = &a;
>>     *aPtr = cast(typeof(a)) (*aPtr + { auto olda = *aPtr; *aPtr = a +
>> 1; return olda; }());
>>     return *aPtr;
>> }()
>
> So you propose the following lowering for e1 += e2:
>
> e1 += e2
>
> -\>
>
> {
>     auto __p = &(e1);
>     *__p = cast(typeof(e1)) (*__p + e2);
> }()
>
> This looks contrived and it's no surprise is inconsistent with opOpAssign as you yourself noted. I prefer the lowering that identifies += to a function calls with two parameters:
>
> e1 += e2
>
> -\>
>
> (ref a, b) { a = (cast(typeof(a)) (a + b); }(e1, e2)
>
>>>> Other code transformation do not require a function call to take place,
>>>> so why would this require one (which force eager evaluation of
>>>> parameters) ?
>>>
>>> Everything needs to be evaluated (and only once).
>>>
>>>> That is also inconsistent with LTR evaluation.
>>>
>>> I don't see how.
>>>
>>
>> a appear on the left of a++. a should be evaluated before a++. You
>> propose that it isn't.
>
> I see, thanks.
>
> Guess we should change the spec no matter what. My money is on the lowering I mentioned.
>
>
> Andrei

I might be a bit confused here, but from what you're saying:
b += a++;
and
b += ++a;

Are doing the same thing in DMD?
March 31, 2015
On 3/31/15 12:18 AM, Orvid King wrote:
>
> I might be a bit confused here, but from what you're saying:
> b += a++;
> and
> b += ++a;
>
> Are doing the same thing in DMD?

No. Lowering of e1 += e2++ is:

e1 += e2++

-\>

(ref a, b) { a = (cast(typeof(a)) (a + b); }(
  e1,
  (ref a) { auto x = a; ++a; return x; }(e2)
)

whereas lowering of e1 += ++e2 is:

e1 += ++e2

-\>

(ref a, b) { a = (cast(typeof(a)) (a + b); }(
  e1,
  (ref a) { ++a; return a; }(e2)
)


Andrei

April 05, 2015
On Tuesday, 31 March 2015 at 08:17:31 UTC, Andrei Alexandrescu wrote:
> On 3/31/15 12:18 AM, Orvid King wrote:
>>
>> I might be a bit confused here, but from what you're saying:
>> b += a++;
>> and
>> b += ++a;
>>
>> Are doing the same thing in DMD?
>
> No. Lowering of e1 += e2++ is:
>
> e1 += e2++
>
> -\>
>
> (ref a, b) { a = (cast(typeof(a)) (a + b); }(
>   e1,
>   (ref a) { auto x = a; ++a; return x; }(e2)
> )
>
> whereas lowering of e1 += ++e2 is:
>
> e1 += ++e2
>
> -\>
>
> (ref a, b) { a = (cast(typeof(a)) (a + b); }(
>   e1,
>   (ref a) { ++a; return a; }(e2)
> )
>
>
> Andrei

Fixed in SDC.
April 05, 2015
On 4/4/15 7:54 PM, deadalnix wrote:
> On Tuesday, 31 March 2015 at 08:17:31 UTC, Andrei Alexandrescu wrote:
>> On 3/31/15 12:18 AM, Orvid King wrote:
>>>
>>> I might be a bit confused here, but from what you're saying:
>>> b += a++;
>>> and
>>> b += ++a;
>>>
>>> Are doing the same thing in DMD?
>>
>> No. Lowering of e1 += e2++ is:
>>
>> e1 += e2++
>>
>> -\>
>>
>> (ref a, b) { a = (cast(typeof(a)) (a + b); }(
>>   e1,
>>   (ref a) { auto x = a; ++a; return x; }(e2)
>> )
>>
>> whereas lowering of e1 += ++e2 is:
>>
>> e1 += ++e2
>>
>> -\>
>>
>> (ref a, b) { a = (cast(typeof(a)) (a + b); }(
>>   e1,
>>   (ref a) { ++a; return a; }(e2)
>> )
>>
>>
>> Andrei
>
> Fixed in SDC.

Awesome, thanks! -- Andrei
1 2
Next ›   Last »