December 31, 2017
On 12/30/17 10:08 PM, Ivan Trombley wrote:
> double[] D = [3.14159];
> 
> Can you guess what D is?  :D
> 

An approximation of a slice of pi.

-Steve
December 31, 2017
On Sunday, December 31, 2017 04:42:01 Tony via Digitalmars-d-learn wrote:
> On Sunday, 31 December 2017 at 04:20:28 UTC, codephantom wrote:
> > On Sunday, 31 December 2017 at 03:57:17 UTC, Tony wrote:
> >> On Sunday, 31 December 2017 at 03:08:05 UTC, Ivan Trombley
> >>
> >> wrote:
> >>> double[] D = [3.14159];
> >>>
> >>> Can you guess what D is?  :D
> >>
> >> It took me a while but I finally came up with "a slice of pi"
> >
> > a slice of pi is irrational.
>
> Even on special occasions?

Of course. Cake is so much better. ;)

- Jonathan M Davis

December 31, 2017
On Sunday, December 31, 2017 01:57:58 Tony via Digitalmars-d-learn wrote:
> On Friday, 29 December 2017 at 23:13:20 UTC, Jonathan M Davis
>
> wrote:
> > The term "slice" is a bit overused in D, meaning a variety of things. It doesn't help that some folks dislike the official terminology. In general, a slice is a contiguous group of elements. A slice of memory would be a contiguous block of memory. A dynamic array therefore refers to a slice of memory and could be called a slice, but it's also the case that using the slice operater on a container is called slicing - e.g. rbt[] would give you a range over the container rbt, and that range is a slice of the container, but it's not an array at all.
>
> For me, it is confusing to use "slice" and "dynamic array" as synonyms. My initial impression was that they must have different code underlying them, and different behavior. I would pick one or the other. It should be:
>
> D Arrays
>    - Static
>    - Dynamic
>
> or
>
> D Arrays
>     - Static
>     - Slice
>
>
> The DLang Tour has a section on Slices that says in bold "Slices and dynamic arrays are the same". I think that sentence deserves an explanation as to why there are two terms being utilized for the same thing. I would prefer that "slice" as a noun was used only for the time when a dynamic array was initialized from a slice of another array. Or better yet - slice was never used as a noun - only a verb or adjective: took a slice of array A to form a slice dynamic array B (or slice-intialized dynamic array B).
>
> D Arrays
>     - Static
>     - Dynamic
>        - Slice-Initialized Dynamic

All dynamic arrays are slices of memory. What changes is what memory they're sliced from. There is no master dynamic array that controls the memory that backs all of these dynamic arrays. They're the same whether they were allocated via new or slices from a static array or sliced from pointers or whatever. _All_ a dynamic array is a pointer and a length - e.g.

struct DynamicArray(T)
{
    size_t length;
    T* ptr;
}

It has no mechanism for managing memory or tracking who owns it. All of that is handled by whatever allocated the memory in the first place. In most cases, that's the GC, but it doesn't have to be. The dynamic array doesn't even have a way to keep track of its capacity. All of that is handled by the GC.

Yes, appending to a dynamic array or calling reserve on it can cause memory to be allocated by the GC, but that's because the GC looks at the capacity of the array (which it calculates based on extra stuff it keeps track of) and sees whether it can increase the length of the array in place (which it can do only if the array is backed by GC-allocated memory, and the capacity is greater than its current length). The GC then may allocate a new block of memory and copy the contents of the array to the new memory, and the runtime will adjust the two members of the dynamic array so that they point to the new block of memory, but the dynamic array itself does none of this - and it all works exactly the same if the dynamic array is backed by non-GC-allocated memory. It's just that the GC will determine that since it's not backed by GC-allocated memory, its capacity is 0, and any operation that would need to increase the length or capacity of the array will need to reallocate (after which, the dynamic array will be backed by GC-allocated memory regardless of what backed it before).

In no case does the dynamic array itself manage its own memory, and there is no concept of the "original" dynamic array that the others come from. As confusing as that may seem at first, that simply isn't how dynamic arrays in D work. Rather than being a container which you can get ranges over, they're a weird hybrid between the two. They have operations that act like they own and manage their own memory, but they really don't.

The D Slices article does an excellent job of explaining all of this. It's just that it calls the GC-allocated memory buffer the dynamic array instead of calling T[] the dynamic array like the language and spec do. Regardless, all non-null dynamic arrays are slices of memory.

- Jonathan M Davis

December 31, 2017
On Sunday, 31 December 2017 at 14:24:40 UTC, Jonathan M Davis wrote:

>
> The D Slices article does an excellent job of explaining all of this. It's just that it calls the GC-allocated memory buffer the dynamic array instead of calling T[] the dynamic array like the language and spec do. Regardless, all non-null dynamic arrays are slices of memory.

The DLang Tour also uses the term slice to refer to T[].

"The type of arr is int[], which is also called a slice."

"A slice consists of two members - a pointer to the starting element and the length of the slice:"




December 31, 2017
On Sunday, December 31, 2017 14:49:40 Tony via Digitalmars-d-learn wrote:
> On Sunday, 31 December 2017 at 14:24:40 UTC, Jonathan M Davis
>
> wrote:
> > The D Slices article does an excellent job of explaining all of this. It's just that it calls the GC-allocated memory buffer the dynamic array instead of calling T[] the dynamic array like the language and spec do. Regardless, all non-null dynamic arrays are slices of memory.
>
> The DLang Tour also uses the term slice to refer to T[].
>
> "The type of arr is int[], which is also called a slice."
>
> "A slice consists of two members - a pointer to the starting element and the length of the slice:"

Presumably, because whoever wrote that preferred the terminology used in the D Slices article. Regardless, it's not wrong to call them slices. It's just less precise, since the term slice refers to more than dynamic arrays.

The DLang Tour should probably be fixed to use the term dynamic array though.

- Jonathan M Davis

January 01, 2018
On Monday, 1 January 2018 at 02:10:14 UTC, Jonathan M Davis wrote:

>
> The DLang Tour should probably be fixed to use the term dynamic array though.

Or embrace both terms but take care that it is clear that they are synonyms and one may be preferred depending on context. As a beginner, I had some confusion seeing both terms used.

There is dual terminology in use outside of dlang.org. The book Programming In D says:
--------------------------------------------------------------------
Slice: Another name for dynamic array.

When I write slice I will specifically mean a slice; and when I write array, I will mean either a slice or a fixed-length array, with no distinction.

Slices

Slices are the same feature as dynamic arrays. They are called dynamic arrays for being used like arrays, and are called slices for providing access to portions of other arrays. They allow using those portions as if they are separate arrays.
-----------------------------------------------------------------------


December 31, 2017
On Monday, January 01, 2018 05:06:46 Tony via Digitalmars-d-learn wrote:
> On Monday, 1 January 2018 at 02:10:14 UTC, Jonathan M Davis wrote:
> > The DLang Tour should probably be fixed to use the term dynamic array though.
>
> Or embrace both terms but take care that it is clear that they are synonyms and one may be preferred depending on context. As a beginner, I had some confusion seeing both terms used.
>
> There is dual terminology in use outside of dlang.org. The book Programming In D says:
> --------------------------------------------------------------------
> Slice: Another name for dynamic array.
>
> When I write slice I will specifically mean a slice; and when I write array, I will mean either a slice or a fixed-length array, with no distinction.
>
> Slices
>
> Slices are the same feature as dynamic arrays. They are called dynamic arrays for being used like arrays, and are called slices for providing access to portions of other arrays. They allow using those portions as if they are separate arrays.
> -----------------------------------------------------------------------

A big problem with the term slice though is that it means more than just dynamic arrays - e.g. you slice a container to get a range over it, so that range is a slice of the container even though no arrays are involved at all. So, you really can't rely on the term slice meaning dynamic array. Whether it does or not depends on the context. That means that the fact that a number of folks have taken to using the term slice to mean T[] like the D Slices article talks about tends to create confusion when the context is not clear. IMHO, the D Slices article should be updated to use the correct terminology, but I don't think that the author is willing to do that.

- Jonathan M Davis

January 01, 2018
On Monday, 1 January 2018 at 02:10:14 UTC, Jonathan M Davis wrote:
> On Sunday, December 31, 2017 14:49:40 Tony via Digitalmars-d-learn wrote:
>> On Sunday, 31 December 2017 at 14:24:40 UTC, Jonathan M Davis
>>
>> wrote:
>> > [...]
>>
>> The DLang Tour also uses the term slice to refer to T[].
>>
>> "The type of arr is int[], which is also called a slice."
>>
>> "A slice consists of two members - a pointer to the starting element and the length of the slice:"
>
> Presumably, because whoever wrote that preferred the terminology used in the D Slices article. Regardless, it's not wrong to call them slices. It's just less precise, since the term slice refers to more than dynamic arrays.
>
> The DLang Tour should probably be fixed to use the term dynamic array though.
>
> - Jonathan M Davis

Editing a page is just one click away - there is an edit button on the top. Any improvements are always welcome!
January 02, 2018
On 1/1/18 12:18 AM, Jonathan M Davis wrote:
> 
> A big problem with the term slice though is that it means more than just
> dynamic arrays - e.g. you slice a container to get a range over it, so that
> range is a slice of the container even though no arrays are involved at all.
> So, you really can't rely on the term slice meaning dynamic array. Whether
> it does or not depends on the context. That means that the fact that a
> number of folks have taken to using the term slice to mean T[] like the D
> Slices article talks about tends to create confusion when the context is not
> clear. IMHO, the D Slices article should be updated to use the correct
> terminology, but I don't think that the author is willing to do that.
The problem with all of this is that dynamic array is a defined term *outside* of D [1]. And it doesn't mean exactly what D calls dynamic arrays.

This is why it's confusing to outsiders, because they are expecting the same thing as a C++ std::vector, or a Java/.Net ArrayList, etc. And D "array slices" (the proper term IMO) are not the same.

I'm willing to change the article to mention "Array slices" instead of just "slices", because that is a valid criticism. But I don't want to change it from slices to dynamic arrays, since the whole article is written around the subtle difference. I think the difference is important.

-Steve

[1] https://en.wikipedia.org/wiki/Dynamic_array
January 02, 2018
On Tuesday, January 02, 2018 07:53:00 Steven Schveighoffer via Digitalmars- d-learn wrote:
> On 1/1/18 12:18 AM, Jonathan M Davis wrote:
> > A big problem with the term slice though is that it means more than just dynamic arrays - e.g. you slice a container to get a range over it, so that range is a slice of the container even though no arrays are involved at all. So, you really can't rely on the term slice meaning dynamic array. Whether it does or not depends on the context. That means that the fact that a number of folks have taken to using the term slice to mean T[] like the D Slices article talks about tends to create confusion when the context is not clear. IMHO, the D Slices article should be updated to use the correct terminology, but I don't think that the author is willing to do that.
> The problem with all of this is that dynamic array is a defined term *outside* of D [1]. And it doesn't mean exactly what D calls dynamic arrays.
>
> This is why it's confusing to outsiders, because they are expecting the same thing as a C++ std::vector, or a Java/.Net ArrayList, etc. And D "array slices" (the proper term IMO) are not the same.
>
> I'm willing to change the article to mention "Array slices" instead of just "slices", because that is a valid criticism. But I don't want to change it from slices to dynamic arrays, since the whole article is written around the subtle difference. I think the difference is important.
>
> -Steve
>
> [1] https://en.wikipedia.org/wiki/Dynamic_array

I completely agree that the distinction between the dynamic array and the memory that backs it is critical to understanding the semantics when copying arrays around, and anyone who thinks that the dynamic array itself directly controls and owns the memory is certainly going to have some problems understanding the full semantics, but I don't agree that it's required to talk about the underlying GC-allocated memory buffer as being the dynamic array for that to be understood - especially when the dynamic array can be backed with other memory to begin with and still have the same semantics (just with a capacity of 0 and thus guaranteed reallocation upon appending or calling reserve). That distinction can be made just fine using the official D terminology.

I also don't agree that the way that D uses the term dynamic array contradicts the wikipedia article. What it describes is very much how D's dynamic arrays behave. It's just that D's dynamic arrays are a bit special in that they let the GC manage the memory instead of encapsulating it all in the type itself, and copying them slices the memory instead of copying it and thus causing an immediate reallocation like you would get with std::vector or treating it as a full-on reference type like Java does. But the semantics of what happens when you append to a D dynamic array are the same as appending to something like std::vector save for the fact that you might end up having the capacity filled sooner, because another dynamic array referring to the same memory grew into that space, resulting in a reallocation - but std::vector would have reallocated as soon as you copied it. So, some of the finer details get a bit confusing if you expect a dynamic array to behave _exactly_ like std::vector, but at a high level, the semantics are basically the same.

On the basis that you seem to be arguing that D's dynamic arrays aren't really dynamic arrays, I could see someone arguing that std::vector isn't a dynamic array, because unlike ArrayList, it isn't a reference type and thus appending to the copy doesn't append to the original - or the other way around; ArrayList isn't a dynamic array, because appending to a "copy" affects the original. The semantics of what happens when copying the array around are secondary to what being a dynamic array actually means, much as they obviously have a significant effect on how you write your code. The critical bits are how the memory is continguous and how appending is amortized to O(1). The semantics of copying clearly vary considerably depending on the exact implementation even if you ignore what D has done.

I think that your article has been a great help, and the fact that you do a good job of describing the distinction between T[] and the memory behind it is critical. I just disagree with the terminology that you used when you did it, and I honestly think that the terminology used has a negative effect on understanding and dealing with dynamic arrays backed by non-GC-allocated memory, because the result seems to be that folks think that there's something different about them and how they behave (since they don't point to a "dynamic array" as your article uses the term), when in reality, there's really no difference in the semantics aside from the fact that their capacity is guaranteed to be 0 and thus reallocation is guaranteed upon appending or calling reserve, whereas for GC-backed dynamic arrays, capacity could be other numbers, and immediate reallocation is not guaranteed any more than it's guaranteed not to happen; it depends on the capacity, but you can always know when a reallocation is going to occur based on the capacity, regardless of what memory backs it.

Yes, if you're dealing with dynamic arrays backed by malloc-ed memory or a static array, you're going to have to worry about the lifetime of those dynamic arrays differently if you don't want @safety problems, and for malloc-ed memory, you're going to have to keep track of a pointer to the original memory so that it can be freed later, since the GC won't do it for you, but all of the semantics of the dynamic array itself are the same. regardless of what memory backs it. Now, maybe that's hard enough to understand that lots of folks would be misunderstanding that and thinking that GC-backed dynamic arrays are inherently different even if your article used the terms in the official manner, but I'm convinced that the way that it refers to dynamic arrays as being the memory buffer rather than T[] itself makes that misunderstanding worse as the article as a whole clears up other misunderstandings.

Regardless, given that the term slice is a rather overloaded term in D, having the article consistently use the term array slice rather than simply slice would be an improvement.

- Jonathan M Davis