December 24, 2011
On Sat, Dec 24, 2011 at 1:45 PM, Timon Gehr <timon.gehr@gmx.ch> wrote:
> On 12/24/2011 08:41 PM, Mr. Anonymous wrote:
>>
>> On 24.12.2011 21:22, Andrew Wiley wrote:
>>>
>>> On Sat, Dec 24, 2011 at 1:08 PM, Timon Gehr<timon.gehr@gmx.ch> wrote:
>>>>
>>>> On 12/24/2011 07:00 PM, Andrew Wiley wrote:
>>>>>
>>>>>
>>>>> On Sat, Dec 24, 2011 at 9:50 AM, Timon Gehr<timon.gehr@gmx.ch> wrote:
>>>>>>
>>>>>>
>>>>>> On 12/24/2011 06:18 PM, Andrew Wiley wrote:
>>>>>>
>>>>>>>
>>>>>>> 2011/12/24 Mr. Anonymous<mailnew4ster@gmail.com>:
>>>>>>>
>>>>>>>> On 24.12.2011 19:01, Denis Shelomovskij wrote:
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> 23.12.2011 22:51, bearophile пишет:
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>>
>>>>>>>>>>> ++a[] works, but a[]++ doesn't.
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> Already known compiler bug.
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> Is it a joke? Array expression in D are for performance reasons to
>>>>>>>>> generate x2-x100 faster code without any compiler optimisations.
>>>>>>>>> Link
>>>>>>>>> to
>>>>>>>>> one of these epic comments (even x100 more epic because of '%' use
>>>>>>>>> instead of 'x###'):
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> https://github.com/D-Programming-Language/druntime/blob/master/src/rt/arraybyte.d#L1127
>>>>>>>>>
>>>>>>>>>
>>>>>>>>>
>>>>>>>>> But `a[]++` should store a copy of `a`, increment elements and
>>>>>>>>> return
>>>>>>>>> stored copy. It is hidden GC allocation. We already have a silent
>>>>>>>>> allocation in closures, but here a _really large_ peace of data
>>>>>>>>> can be
>>>>>>>>> allocated. Yes, this allocation sometimes can be optimized out
>>>>>>>>> but not
>>>>>>>>> always.
>>>>>>>>>
>>>>>>>>> IMHO, D should not have `a[]++` operator.
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>>
>>>>>>>> Why should it store a copy? o_O
>>>>>>>> I also don't see any allocations in the code on the URL above.
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>>
>>>>>>> int a_orig = a++;
>>>>>>> int[] arr_orig = arr[]++;
>>>>>>>
>>>>>>> If ++ is going to be applied to an array, it needs to have the same meaning as it does elsewhere. After this operation, arr_orig and arr must refer to different arrays for that to be true.
>>>>>>
>>>>>>
>>>>>>
>>>>>>
>>>>>> Not necessarily.
>>>>>>
>>>>>> class D{
>>>>>> int payload;
>>>>>> D opUnary(string op:"++")(){payload++; return this;}
>>>>>> }
>>>>>>
>>>>>> void main() {
>>>>>> D d = new D;
>>>>>> assert(d.payload == 0);
>>>>>> assert(d++.payload == 1);
>>>>>> }
>>>>>
>>>>>
>>>>>
>>>>> That doesn't match integer semantics:
>>>>> int a = 0;
>>>>> assert(a++ == 0);
>>>>> assert(a == 1);
>>>>
>>>>
>>>>
>>>> Yes, that was my point.
>>>>
>>>
>>> Then I'm not understanding what you're trying to prove.
>>> I'm saying that if we implement a postfix ++ operator for arrays,
>>> keeping the language consistent would require it to make a copy if the
>>> user stores a copy of the original array. I guess it could be argued
>>> that since arrays have hybrid value/reference semantics, no copy
>>> should be made and the original should change.
>>>
>>> Actually, looking at it from that angle, a[]++ is fundamentally ambiguous because it could have value semantics or reference semantics, so I would argue that we shouldn't have it for that reason. '++a' and 'a += 1' do not have such ambiguities.
>>
>>
>> Maybe you're right, but a[]++; alone, imo, should compile.
>
>
> +1.

You could special case this, but I'd be happy with an error that told you to use one of the working alternatives.
December 24, 2011
On 24.12.2011 19:18, Andrew Wiley wrote:
> 2011/12/24 Mr. Anonymous<mailnew4ster@gmail.com>:
>> On 24.12.2011 19:01, Denis Shelomovskij wrote:
>>>
>>> 23.12.2011 22:51, bearophile пишет:
>>>>>
>>>>> ++a[] works, but a[]++ doesn't.
>>>>
>>>> Already known compiler bug.
>>>
>>>
>>> Is it a joke? Array expression in D are for performance reasons to
>>> generate x2-x100 faster code without any compiler optimisations. Link to
>>> one of these epic comments (even x100 more epic because of '%' use
>>> instead of 'x###'):
>>>
>>> https://github.com/D-Programming-Language/druntime/blob/master/src/rt/arraybyte.d#L1127
>>>
>>>
>>> But `a[]++` should store a copy of `a`, increment elements and return
>>> stored copy. It is hidden GC allocation. We already have a silent
>>> allocation in closures, but here a _really large_ peace of data can be
>>> allocated. Yes, this allocation sometimes can be optimized out but not
>>> always.
>>>
>>> IMHO, D should not have `a[]++` operator.
>>
>>
>> Why should it store a copy? o_O
>> I also don't see any allocations in the code on the URL above.
>
> int a_orig = a++;
> int[] arr_orig = arr[]++;
>
> If ++ is going to be applied to an array, it needs to have the same
> meaning as it does elsewhere. After this operation, arr_orig and arr
> must refer to different arrays for that to be true.

Actually, when I think of it:

int a_orig = a++;
int[] arr_orig = arr[]++;

Should be read as:

int a_orig = a;
++a;
int[] arr_orig = arr[];
++arr[];

(If I'm not mistaken, it was written in the TDPL book)

Which means no copy of arr is made, and both arrays (which reference to the same block) are affected.
December 25, 2011
25.12.2011 0:48, Mr. Anonymous пишет:
> Actually, when I think of it:
>
> int a_orig = a++;
> int[] arr_orig = arr[]++;
>
> Should be read as:
>
> int a_orig = a;
> ++a;
> int[] arr_orig = arr[];
> ++arr[];
>
> (If I'm not mistaken, it was written in the TDPL book)
>
> Which means no copy of arr is made, and both arrays (which reference to
> the same block) are affected.

OK. As I wrote: "Yes, this allocation sometimes can be optimized out but not always.". Consider this:
---
void main()
{
    int[] a = new int[5];
    void f(int[] b)
    {
        // Here we assume that b is unchanged a.
        // As these array differ we need a copy.
        assert(b[0] == 0);
        assert(a[0] == 1);
    }
    f(a[]++); // Note: compilation error now
}
---
Why not to rewrite `f(a[]++);` as `f(a); ++a[];`? Because postincrement is expected to increment its argument when it is executed. It just returns an unchanged copy. Analogous D code with integers illustrates this:
---
void main()
{
    int a;
    void f(int b)
    {
        assert(b == 0);
        assert(a == 1);
    }
    f(a++);
}
---
December 29, 2011
On 25.12.2011 11:28, Denis Shelomovskij wrote:
> OK. As I wrote: "Yes, this allocation sometimes can be optimized out but
> not always.". Consider this:
> ---
> void main()
> {
> int[] a = new int[5];
> void f(int[] b)
> {
> // Here we assume that b is unchanged a.
> // As these array differ we need a copy.
> assert(b[0] == 0);
> assert(a[0] == 1);
> }
> f(a[]++); // Note: compilation error now
> }
> ---
> Why not to rewrite `f(a[]++);` as `f(a); ++a[];`? Because postincrement
> is expected to increment its argument when it is executed. It just
> returns an unchanged copy. Analogous D code with integers illustrates this:
> ---
> void main()
> {
> int a;
> void f(int b)
> {
> assert(b == 0);
> assert(a == 1);
> }
> f(a++);
> }
> ---
I wasn't familiar with this postincrement behavior. I would expect both a and b to be 0 inside f().
Anyway, what do you suggest? To leave it not compilable?

My original point was to just allow:
a[]++;
More complicated scenarios like the one above is beyond my knowledge, as I'm only learning the language, but I think they have to be addressed as well.
1 2 3 4
Next ›   Last »