July 29, 2014
On Sunday, 27 July 2014 at 05:51:46 UTC, Jakob Ovrum wrote:
> On Saturday, 26 July 2014 at 23:06:02 UTC, Andrew Godfrey wrote:
>> Thereafter can come sub-slice examples and so on.
>> Does this make sense?
>
> Yes, the reference documentation is pretty terrible with naming of various array concepts.
>
> IIRC, when this was discussed in the past, a majority seemed to be in favour of using "slice" and "dynamic array" for their respective concepts instead of the current situation, but I also remember there was some opposition (for reason I can't remember). A pull request updating the documentation to use slice/dynamic array might weed them out ;)

I gave this a try, and overall it looks like an improvement, but I think we need another name than "slice". The reason is that the slice operator is a distinct thing and interacts with the "slice" in strange ways. When I next get time I'll try updating it to use the term "array reference". That is:

int[] a; // defines an array reference, a
int[3] b;
a = b[1..3]; // updates the array reference a to refer to a slice of b
July 29, 2014
On Tuesday, 29 July 2014 at 07:46:34 UTC, Andrew Godfrey wrote:
> On Sunday, 27 July 2014 at 05:51:46 UTC, Jakob Ovrum wrote:
>> On Saturday, 26 July 2014 at 23:06:02 UTC, Andrew Godfrey wrote:
>>> Thereafter can come sub-slice examples and so on.
>>> Does this make sense?
>>
>> Yes, the reference documentation is pretty terrible with naming of various array concepts.
>>
>> IIRC, when this was discussed in the past, a majority seemed to be in favour of using "slice" and "dynamic array" for their respective concepts instead of the current situation, but I also remember there was some opposition (for reason I can't remember). A pull request updating the documentation to use slice/dynamic array might weed them out ;)
>
> I gave this a try, and overall it looks like an improvement, but I think we need another name than "slice". The reason is that the slice operator is a distinct thing and interacts with the "slice" in strange ways. When I next get time I'll try updating it to use the term "array reference". That is:
>
> int[] a; // defines an array reference, a
> int[3] b;
> a = b[1..3]; // updates the array reference a to refer to a slice of b

IMO slice fits quite well for both. `b[1..3]` is a slice (or refers to one?), and `a` is, too. After the assignment, both slices are equal. But I see that there is an ambiguity when we talk about "copying a slice", which could also be interpreted as "copying what the slice refers to".
July 29, 2014
On Tuesday, 29 July 2014 at 07:46:34 UTC, Andrew Godfrey wrote:
> On Sunday, 27 July 2014 at 05:51:46 UTC, Jakob Ovrum wrote:
>> On Saturday, 26 July 2014 at 23:06:02 UTC, Andrew Godfrey wrote:
>>> Thereafter can come sub-slice examples and so on.
>>> Does this make sense?
>>
>> Yes, the reference documentation is pretty terrible with naming of various array concepts.
>>
>> IIRC, when this was discussed in the past, a majority seemed to be in favour of using "slice" and "dynamic array" for their respective concepts instead of the current situation, but I also remember there was some opposition (for reason I can't remember). A pull request updating the documentation to use slice/dynamic array might weed them out ;)
>
> I gave this a try, and overall it looks like an improvement, but I think we need another name than "slice". The reason is that the slice operator is a distinct thing and interacts with the "slice" in strange ways. When I next get time I'll try updating it to use the term "array reference". That is:
>
> int[] a; // defines an array reference, a
> int[3] b;
> a = b[1..3]; // updates the array reference a to refer to a slice of b

You can look at it like this: There are no builtin dynamic arrays in D, there are only slices (windows on to arbitrary memory) and static arrays (a block of stack memory, treated a value type).

What you choose your slice to be a window on is your own business.

int[] a = new int[10]; //a window on to some new gc memory
int[3] b; //a static array
a = b[1 .. 3]; //a window on to part of of b
a = (cast(int*)core.stdc.stdlib.malloc(10*int.sizeof))[0 .. 10];
  //a window on to some new memory on the C heap.
July 29, 2014
You don't say anything below that does not work when I replace "dynamic array"s with "slice"s. Let's see... (I mark every such replaced-by-me-"slice" with double stars.)

On 07/28/2014 06:35 PM, Jonathan M Davis wrote:

> On Monday, 28 July 2014 at 22:29:04 UTC, Ali Çehreli wrote:
>> On 07/27/2014 01:49 AM, Jonathan M Davis wrote:
>> > difference between a dynamic array and a slice (there really
>> isn't any).
>>
>> At the risk of beating this never-dying horse, when you say that, I
>> don't think you can explain the following code:
>>
>>     int[] a = [ 1, 2, 3 ];
>>     int[] b = a;
>>
>> According to your terminology, 'a' is a dynamic array and 'b' is
>> another dynamic array. Knowing how good you know D, I can't understand
>> how you think that way. In fact, both 'a' and 'b' are slices into the
>> single dynamic array. The dynamic array is managed by the GC. So,
>> there are three entities in that code: One dynamic array and two slices.
>
> It's simple, D's **slices** _never_ own their memory. It's owned by
> the GC, or it's a slice of a static array, or it points to a buffer that
> was malloc-ed, etc. The type T[] says _nothing_ about who or what owns
> the memory or what backs the array. Understanding how it works when
> they're generated by the GC is very helpful in determining when a
> **slice** / slice is likely to be reallocated, but it's pretty
> irrelevant to the type itself.
>
> In your example, both a and b are **slices** which are slices of the
> same underlying block of memory. It's a and b which are the **slices**,
> not the buffer. From the type system's perspective, this would
> be the same
>
> int[3] z = [1, 2, 3];
> int[] a = z;
> int[] b = a;
>
> a and by are still exactly the same type - **slices** - and they
> will behave exactly the same save for the fact that due to the fact that
> they're now backed by a static array rather than the GC, their capacity
> is guaranteed to be 0, and it's unsafe for them to escape from the scope
> of z.
>
> The underlying buffer for a GC-backed **slice** isn't even a D
> array. It's a druntime-specific data structure which holds a buffer via
> pointer.
>
> The array article does a great job of explaining a lot of the details
> about how D arrays work (especially those backed by the GC), but it got
> the terminology wrong, and I definitely think that it should be fixed.
>
> - Jonathan M Davis

The array article uses terminology that removes confusion.

Ali

July 29, 2014
On Tue, 29 Jul 2014 02:54:37 -0700
Ali Çehreli via Digitalmars-d <digitalmars-d@puremagic.com> wrote:

> You don't say anything below that does not work when I replace "dynamic array"s with "slice"s. Let's see... (I mark every such replaced-by-me-"slice" with double stars.)

Because they're the same thing as far as D is concerned.

> On 07/28/2014 06:35 PM, Jonathan M Davis wrote:
>
>  > On Monday, 28 July 2014 at 22:29:04 UTC, Ali Çehreli wrote:
>  >> On 07/27/2014 01:49 AM, Jonathan M Davis wrote:
>  >> > difference between a dynamic array and a slice (there really
>  >> isn't any).
>  >>
>  >> At the risk of beating this never-dying horse, when you say that,
>  >> I don't think you can explain the following code:
>  >>
>  >>     int[] a = [ 1, 2, 3 ];
>  >>     int[] b = a;
>  >>
>  >> According to your terminology, 'a' is a dynamic array and 'b' is
>  >> another dynamic array. Knowing how good you know D, I can't
>  >> understand how you think that way. In fact, both 'a' and 'b' are
>  >> slices into the single dynamic array. The dynamic array is
>  >> managed by the GC. So, there are three entities in that code: One
>  >> dynamic array and two slices.
>  >
>  > It's simple, D's **slices** _never_ own their memory. It's owned by
>  > the GC, or it's a slice of a static array, or it points to a
>  > buffer that was malloc-ed, etc. The type T[] says _nothing_ about
>  > who or what owns the memory or what backs the array. Understanding
>  > how it works when they're generated by the GC is very helpful in
>  > determining when a **slice** / slice is likely to be reallocated,
>  > but it's pretty irrelevant to the type itself.
>  >
>  > In your example, both a and b are **slices** which are slices of
>  > the same underlying block of memory. It's a and b which are the
>  > **slices**, not the buffer. From the type system's perspective,
>  > this would be the same
>  >
>  > int[3] z = [1, 2, 3];
>  > int[] a = z;
>  > int[] b = a;
>  >
>  > a and by are still exactly the same type - **slices** - and they
>  > will behave exactly the same save for the fact that due to the
>  > fact that they're now backed by a static array rather than the GC,
>  > their capacity is guaranteed to be 0, and it's unsafe for them to
>  > escape from the scope of z.
>  >
>  > The underlying buffer for a GC-backed **slice** isn't even a D
>  > array. It's a druntime-specific data structure which holds a
>  > buffer via pointer.
>  >
>  > The array article does a great job of explaining a lot of the
>  > details about how D arrays work (especially those backed by the
>  > GC), but it got the terminology wrong, and I definitely think that
>  > it should be fixed.
>  >
>  > - Jonathan M Davis
>
> The array article uses terminology that removes confusion.

It uses terminology that does not match the language spec. It could use the correct terminology and still remove confusion.

- Jonathan M Davis

July 29, 2014
On Tuesday, 29 July 2014 at 08:41:48 UTC, Marc Schütz wrote:
> On Tuesday, 29 July 2014 at 07:46:34 UTC, Andrew Godfrey wrote:
>>
>> I gave this a try, and overall it looks like an improvement, but I think we need another name than "slice". The reason is that the slice operator is a distinct thing and interacts with the "slice" in strange ways. When I next get time I'll try updating it to use the term "array reference". That is:
>>
>> int[] a; // defines an array reference, a
>> int[3] b;
>> a = b[1..3]; // updates the array reference a to refer to a slice of b
>
> IMO slice fits quite well for both. `b[1..3]` is a slice (or refers to one?), and `a` is, too. After the assignment, both slices are equal. But I see that there is an ambiguity when we talk about "copying a slice", which could also be interpreted as "copying what the slice refers to".

That wasn't meant to be a motivating example.
The totality of what I have so far is really what makes me think this - it's too big to share here, but I suppose I could submit a PR for rejection?

Here's an attempt at a short motivating example:

    int[3] a = [1, 0, -1];
    int[] b = a;
    int[] c = new int[4];

    b[] = c[1..4];
    assert(a[2] == 0);

    // Using the proposed 'slice' term, an exhaustive description of the above operation is:
    // This copies a slice of the slice c onto the slice b (which refers to a).
    //
    // If we instead call b and c "array references", the description reads:
    // This copies a slice of the array referenced by c, onto the array referenced by b (which is a).
July 29, 2014
On Tuesday, 29 July 2014 at 16:54:48 UTC, Andrew Godfrey wrote:
> On Tuesday, 29 July 2014 at 08:41:48 UTC, Marc Schütz wrote:
>> On Tuesday, 29 July 2014 at 07:46:34 UTC, Andrew Godfrey wrote:
>>>
>>> I gave this a try, and overall it looks like an improvement, but I think we need another name than "slice". The reason is that the slice operator is a distinct thing and interacts with the "slice" in strange ways. When I next get time I'll try updating it to use the term "array reference". That is:
>>>
>>> int[] a; // defines an array reference, a
>>> int[3] b;
>>> a = b[1..3]; // updates the array reference a to refer to a slice of b
>>
>> IMO slice fits quite well for both. `b[1..3]` is a slice (or refers to one?), and `a` is, too. After the assignment, both slices are equal. But I see that there is an ambiguity when we talk about "copying a slice", which could also be interpreted as "copying what the slice refers to".
>
> That wasn't meant to be a motivating example.
> The totality of what I have so far is really what makes me think this - it's too big to share here, but I suppose I could submit a PR for rejection?
>
> Here's an attempt at a short motivating example:
>
>     int[3] a = [1, 0, -1];
>     int[] b = a;
>     int[] c = new int[4];
>
>     b[] = c[1..4];
>     assert(a[2] == 0);
>
>     // Using the proposed 'slice' term, an exhaustive description of the above operation is:
>     // This copies a slice of the slice c onto the slice b (which refers to a).
>     //
>     // If we instead call b and c "array references", the description reads:
>     // This copies a slice of the array referenced by c, onto the array referenced by b (which is a).

Playing the devil's advocate:

Yes, it does so by assigning a slice from `c` to a slice from `b`.
July 30, 2014
On Tuesday, 29 July 2014 at 20:06:28 UTC, Marc Schütz wrote:
>>    int[3] a = [1, 0, -1];
>>    int[] b = a;
>>    int[] c = new int[4];
>>
>>    b[] = c[1..4];
>>    assert(a[2] == 0);
>>
>>    // This copies a slice of the slice c onto the slice b (which refers to a).
>
> Playing the devil's advocate:
>
> Yes, it does so by assigning a slice from `c` to a slice from `b`.

Let's try to explain why this:
    b = c[1..4];
changes what b refers to, while this:
    b[] = c[1..4];
copies.

Well, if you assign a slice to a slice, that means 'copy elements'.
But if you assign a slice to <what b is>, that means change the reference.
July 30, 2014
fyi, here's what I have so far.
I haven't yet added the cross-references we talked about at the
start of the thread. I'll be away for a few weeks soon, so
won't have much more time until after that.

I'm hoping this link is public. It seemed public:

https://github.com/AndrewGodfrey/dlang.org/commit/463b5656151616e2a164ad414cf2bd61d1b84beb
July 30, 2014
On Wednesday, 30 July 2014 at 02:08:30 UTC, Andrew Godfrey wrote:
> fyi, here's what I have so far.
> I haven't yet added the cross-references we talked about at the
> start of the thread. I'll be away for a few weeks soon, so
> won't have much more time until after that.
>
> I'm hoping this link is public. It seemed public:
>
> https://github.com/AndrewGodfrey/dlang.org/commit/463b5656151616e2a164ad414cf2bd61d1b84beb

I'm completely opposed to changing the official terminology. Per both the spec and TDPL T[] is both a dynamic array and a slice, and I see no reason to change that. And as far as I can tell it's in line with how dynamic arrays are described on Wikipedia:

https://en.wikipedia.org/wiki/Dynamic_array

It's just that the dynamic arrays in D do not own their own memory, and it's the GC which manages dealing with expanding the memory with amortized cost. So, as far as I can tell, T[] follows the expected semantics of dynamic arrays with a few extra capabilities tacked on.

What does trying to change the terminology buy you? Having it be more in line with the array article? If anything, the article should be updated to match the official terminology, not change the terminology to match the article.

It's correct to say that T[] is a slice, because it's always a slice of some chunk of memory - be it from the GC, a static array, malloc, etc. And it's correct to say that T[] is a dynamic array, because it supports all of the operations that a dynamic array is supposed to support. It just comes with the added benefit of being able to have multiple arrays refer to the same memory until one of them has to reallocate due to a lack of available capacity (which is exactly how dynamic arrays work in other languages when you append to them and they don't have enough available space to grow in place).

I do not understand how any of you can claim that T[] is not a dynamic array. Just because it doesn't manage its own memory? The GC manages it in a manner that gives T[] all of the expected semantics of a dynamic array with the added benefit that we can even append onto a dynamic array that's a slice of non-GC-allocated memory (though that makes it so that it is then GC-allocated when it gets reallocated). What about T[] is _not_ a dynamic array?

- Jonathan M Davis