December 24, 2011 Re: Reading about D: few questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Timon Gehr | 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 Re: Reading about D: few questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Andrew Wiley | 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 Re: Reading about D: few questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Mr. Anonymous | 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 Re: Reading about D: few questions | ||||
---|---|---|---|---|
| ||||
Posted in reply to Denis Shelomovskij | 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.
|
Copyright © 1999-2021 by the D Language Foundation