July 30, 2014
On Wednesday, 30 July 2014 at 05:55:58 UTC, Jonathan M Davis wrote:
> I'm completely opposed to changing the official terminology.
Why?

What buys it, to have two terms "slice" and "dynamic array" if they mean exactly the same thing?
Especially if we have two different things, the memory and the reference to the memory, but both terms are only adressin the second thing.
I would prefer to have one term meaning the one thing and the other term meaning the other thing.
Words are changing meaning over the years, and I think it is very instructive to use "dynamic array" to mean the memory, and "slice" to mean the reference to the memory - as done in the article. May be that was not the original meaning of those terms but it is useful, instructive and unambigous, so it should go in the official terminology. (otherwise we would need a new, third term to describe the "other thing" that is not directly accessible in the current language spec wording - but we have none and it would only increase the confusion).
July 30, 2014
> What about T[] is _not_ a dynamic array?

Now that I've done this exercise I can answer more crisply:
When T[] is an lvalue, it behaves like a reference, not a dynamic array.
August 01, 2014
On Wednesday, 30 July 2014 at 09:52:15 UTC, Andrew Godfrey wrote:
>
>> What about T[] is _not_ a dynamic array?
>
> Now that I've done this exercise I can answer more crisply:
> When T[] is an lvalue, it behaves like a reference, not a dynamic array.

So the fact that it slices rather than copies is enough to make it not a dynamic array. As far as I can tell, the copying behavior of a dynamic array has nothing to do with it being a dynamic array. It's the facts that you can append to, it maintains extra capacity to make appending efficient, and it reallocates when it runs out of extra capacity (making appending an amortized O(1)) that make an array a dynamic array. And T[] does that.

- Jonathan M Davis
August 01, 2014
On Wednesday, 30 July 2014 at 06:11:58 UTC, Dominikus Dittes Scherkl wrote:
> On Wednesday, 30 July 2014 at 05:55:58 UTC, Jonathan M Davis wrote:
>> I'm completely opposed to changing the official terminology.
> Why?
>
> What buys it, to have two terms "slice" and "dynamic array" if they mean exactly the same thing?
> Especially if we have two different things, the memory and the reference to the memory, but both terms are only adressin the second thing.
> I would prefer to have one term meaning the one thing and the other term meaning the other thing.
> Words are changing meaning over the years, and I think it is very instructive to use "dynamic array" to mean the memory, and "slice" to mean the reference to the memory - as done in the article. May be that was not the original meaning of those terms but it is useful, instructive and unambigous, so it should go in the official terminology. (otherwise we would need a new, third term to describe the "other thing" that is not directly accessible in the current language spec wording - but we have none and it would only increase the confusion).

The "other thing" is just a block of memory managed by the GC and which keeps track of the farthest into the block a particular slice / dynamic array has grown. It doesn't actually act like a dynamic array at all, because it doesn't ever grow. It's just used by the GC to provide memory for dynamic arrays and is only associated with a particular dynamic array until that array is reallocated. Calling that block of memory a dynamic array would be like calling the guts of a std::vector a dynamic array instead calling std::vector a dynamic array. It's just the memory and bookkeeping that backs the dynamic array.

And dynamic array and slice are already not entirely the same, because of more general slicing operations. A dynamic array is always a slice, but if you're talking about the language in general and not arrays specifically, a slice could be something else - e.g. you can slice a DList to get a range over it. It's less common that those are referred to as slices, but they essentially are, and you use opSlice to get them.

I'm increasingly tempted to just write up a new article that uses the correct terminology. And if I can do that properly, then maybe it'll help clear up the confusion.

- Jonathan M Davis
August 01, 2014
Going through other .dd files, I found an error in expression.dd.
It says "For static or dynamic arrays, identity is defined as referring
to the same array elements and the same number of elements."

Well, in fact:

unittest {
    // expression.dd says that equality AND IDENTITY compare elements and sizes, for both "static and dynamic arrays". Gaah!

    int[] a = new int[3];
    int[] b = new int[3];
    assert(a == b);
    assert(a !is b); // Nope! The doc is wrong!

    // So then:

    b = a;
    assert(b is a); // Now b points to a, and 'is' does what I'd expect.
    // But evidently it's because it compared the array references - not
    // the elements and sizes!
}

I would NOT recommend updating the compiler to match what the doc says.
The current behavior is consistent with how assignment to an array reference behaves.
August 01, 2014
Pull request:
https://github.com/D-Programming-Language/dlang.org/pull/623

fyi, I will be away for 3 weeks, mostly unavailable but
may be able to respond occasionally.
August 01, 2014
On Friday, 1 August 2014 at 06:18:06 UTC, Jonathan M Davis wrote:
> On Wednesday, 30 July 2014 at 06:11:58 UTC, Dominikus Dittes Scherkl wrote:
>> [...]
>> should go in the official terminology. (otherwise we would need a new, third term to describe the "other thing" that is not directly accessible in the current language spec wording - but we have none and it would only increase the confusion).
>
> The "other thing" is just a block of memory managed by the GC and which keeps track of the farthest into the block a particular slice / dynamic array has grown. It doesn't actually act like a dynamic array at all, because it doesn't ever grow.
Really?
If I append to my slice, a new "just block of memory" gets allocated, data copied there and my reference changed to point to this new block. Isn't that what everybody describes as that what a dynamic array does?

Ok, I'm not absolutely sure which part of the runtime performs these changes - if it is the GC or the opAppend of arrays or whatever, but the block of memory together with these operations is really what I would call a "dynamic array".

> It's just used by the GC to provide memory for dynamic arrays and is only associated with a particular dynamic array until that array is reallocated. Calling that block of memory a dynamic array would be like calling the guts of a std::vector a dynamic array instead calling std::vector a dynamic array. It's just the memory and bookkeeping that backs the dynamic array.
If a distinction between vector and its backing would be useful, yes I would say it is reasonable to call the backing "dynamic array".

> And dynamic array and slice are already not entirely the same, because of more general slicing operations. A dynamic array is always a slice, but if you're talking about the language in general and not arrays specifically, a slice could be something else - e.g. you can slice a DList to get a range over it. It's less common that those are referred to as slices, but they essentially are, and you use opSlice to get them.
Nice. So we have slices with dynamic array as background and we have slices with different background - even more reason to distinguish slice and dynamic array cleanly.

> I'm increasingly tempted to just write up a new article that uses the correct terminology. And if I can do that properly, then maybe it'll help clear up the confusion.
Yes, do that. I'm eager to read it and see, if it is still as enlightening as the old article was.
August 01, 2014
On Friday, 1 August 2014 at 07:51:32 UTC, Andrew Godfrey wrote:
> Going through other .dd files, I found an error in expression.dd.
> It says "For static or dynamic arrays, identity is defined as referring
> to the same array elements and the same number of elements."
>
> Well, in fact:
>
> unittest {
>     // expression.dd says that equality AND IDENTITY compare elements and sizes, for both "static and dynamic arrays". Gaah!
>
>     int[] a = new int[3];
>     int[] b = new int[3];
>     assert(a == b);
>     assert(a !is b); // Nope! The doc is wrong!
>
>     // So then:
>
>     b = a;
>     assert(b is a); // Now b points to a, and 'is' does what I'd expect.
>     // But evidently it's because it compared the array references - not
>     // the elements and sizes!
> }
>
> I would NOT recommend updating the compiler to match what the doc says.
> The current behavior is consistent with how assignment to an array reference behaves.

Rereading this, the original text did say "refers to". So calling that an "error" may be a bit strong.
August 01, 2014
On Friday, 1 August 2014 at 07:51:32 UTC, Andrew Godfrey wrote:
> Going through other .dd files, I found an error in expression.dd.
> It says "For static or dynamic arrays, identity is defined as referring
> to the same array elements and the same number of elements."
>
> Well, in fact:
>
> unittest {
>     // expression.dd says that equality AND IDENTITY compare elements and sizes, for both "static and dynamic arrays". Gaah!
>
>     int[] a = new int[3];
>     int[] b = new int[3];
>     assert(a == b);
>     assert(a !is b); // Nope! The doc is wrong!
>
>     // So then:
>
>     b = a;
>     assert(b is a); // Now b points to a, and 'is' does what I'd expect.
>     // But evidently it's because it compared the array references - not
>     // the elements and sizes!
> }
>
> I would NOT recommend updating the compiler to match what the doc says.
> The current behavior is consistent with how assignment to an array reference behaves.

I think the docs might can be cleared up in this regard, but from my reading, the docs are correct on this.

    int[] a = new int[3];
and
    int[] b = new int[3];

Do not refer to the same elements. They are two different allocations that happen to look alike and compare equal, but they aren't referring to the same point in memory.

To prove this, you can simply do `a[0] = 1;` ... did `b[0]` "change" as well? (No). Then they couldn't possibly have been referring to the same thing.

What the docs are saying by "referring to the same array elements and the same number of elements": basically, an array in D is simply a pointer + length struct. The `is` operator essentially does a bitwise compare, so naturally `a is b` only returns true when they are bitwise identical structs, which must mean they are the same in both pointer and in length, which naturally means that `a == b` as well. There's no need to compare elements since there's no way something doesn't equal itself unless some weird trickery is going on (concurrent modification?).

You can imagine `is` to mean `a.ptr == b.ptr && a.length == b.length` (or that they refer to the same array and they have the same number of elements), but implemented in what is probably a more efficient manner.
August 02, 2014
On Friday, 1 August 2014 at 21:36:14 UTC, Chris Cain wrote:
> On Friday, 1 August 2014 at 07:51:32 UTC, Andrew Godfrey wrote:
>> Going through other .dd files, I found an error in expression.dd.
>> It says "For static or dynamic arrays, identity is defined as referring
>> to the same array elements and the same number of elements."
>>
>> Well, in fact:
>>
>> unittest {
>>    // expression.dd says that equality AND IDENTITY compare elements and sizes, for both "static and dynamic arrays". Gaah!
>>
>>    int[] a = new int[3];
>>    int[] b = new int[3];
>>    assert(a == b);
>>    assert(a !is b); // Nope! The doc is wrong!
>>
>>    // So then:
>>
>>    b = a;
>>    assert(b is a); // Now b points to a, and 'is' does what I'd expect.
>>    // But evidently it's because it compared the array references - not
>>    // the elements and sizes!
>> }
>>
>> I would NOT recommend updating the compiler to match what the doc says.
>> The current behavior is consistent with how assignment to an array reference behaves.
>
> I think the docs might can be cleared up in this regard, but from my reading, the docs are correct on this.
>
>     int[] a = new int[3];
> and
>     int[] b = new int[3];
>
> Do not refer to the same elements. They are two different allocations that happen to look alike and compare equal, but they aren't referring to the same point in memory.
>
> To prove this, you can simply do `a[0] = 1;` ... did `b[0]` "change" as well? (No). Then they couldn't possibly have been referring to the same thing.
>
> What the docs are saying by "referring to the same array elements and the same number of elements": basically, an array in D is simply a pointer + length struct. The `is` operator essentially does a bitwise compare, so naturally `a is b` only returns true when they are bitwise identical structs, which must mean they are the same in both pointer and in length, which naturally means that `a == b` as well. There's no need to compare elements since there's no way something doesn't equal itself unless some weird trickery is going on (concurrent modification?).
>
> You can imagine `is` to mean `a.ptr == b.ptr && a.length == b.length` (or that they refer to the same array and they have the same number of elements), but implemented in what is probably a more efficient manner.

Yes, I was a bit terse in my previous retraction (was low on time). I realized this is what the doc was actually saying. The edit in the PR stands, but my description of it as fixing an "error" is incorrect.
The language was just a bit confusing, perhaps.
I am unable to fix the PR description at the moment but that shouldn't prevent review of the PR itself.