www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Slices and Dynamic Arrays

reply Tony <tonytdominguez aol.com> writes:
In DLang Tour:Arrays
https://tour.dlang.org/tour/en/basics/arrays

there is:
-----------------------------------------------
int size = 8; // run-time variable
int[] arr = new int[size];

The type of arr is int[], which is a slice.
-----------------------------------------------

In "D Slices"
https://dlang.org/d-array-article.html

there is:
-----------------------------------------------
int[] a;             // a is a slice
------------------------------------------------

Based on those two web pages it appears that the name for a 
dynamic array <reference?> in D is "slice". That is, anytime you 
have a dynamic array (even a null reference version) it is called 
a slice. Is that correct?
Dec 29 2017
next sibling parent Adam D. Ruppe <destructionator gmail.com> writes:
On Friday, 29 December 2017 at 22:32:01 UTC, Tony wrote:
 Based on those two web pages it appears that the name for a 
 dynamic array <reference?> in D is "slice". That is, anytime 
 you have a dynamic array (even a null reference version) it is 
 called a slice. Is that correct?
Not exactly, but basically. read this for a bit more info https://dlang.org/d-array-article.html A slice is a bit more general than a dynamic array. You can slice into a static array, or any buffer really. The slice just also acts as a dynamic array and can create one on-demand if you append to it, and also slices are how D represents the underlying dynamic arrays to user code.
Dec 29 2017
prev sibling next sibling parent Muld <2 2.2> writes:
On Friday, 29 December 2017 at 22:32:01 UTC, Tony wrote:
 In DLang Tour:Arrays
 https://tour.dlang.org/tour/en/basics/arrays

 there is:
 -----------------------------------------------
 int size = 8; // run-time variable
 int[] arr = new int[size];

 The type of arr is int[], which is a slice.
 -----------------------------------------------

 In "D Slices"
 https://dlang.org/d-array-article.html

 there is:
 -----------------------------------------------
 int[] a;             // a is a slice
 ------------------------------------------------

 Based on those two web pages it appears that the name for a 
 dynamic array <reference?> in D is "slice". That is, anytime 
 you have a dynamic array (even a null reference version) it is 
 called a slice. Is that correct?
Not really, cause you can take a "slice" of a linked list (though inefficiently), but a linked list isn't an array. You can also take a "slice" of a stack allocated array.
Dec 29 2017
prev sibling next sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Friday, December 29, 2017 22:32:01 Tony via Digitalmars-d-learn wrote:
 In DLang Tour:Arrays
 https://tour.dlang.org/tour/en/basics/arrays

 there is:
 -----------------------------------------------
 int size = 8; // run-time variable
 int[] arr = new int[size];

 The type of arr is int[], which is a slice.
 -----------------------------------------------

 In "D Slices"
 https://dlang.org/d-array-article.html

 there is:
 -----------------------------------------------
 int[] a;             // a is a slice
 ------------------------------------------------

 Based on those two web pages it appears that the name for a
 dynamic array <reference?> in D is "slice". That is, anytime you
 have a dynamic array (even a null reference version) it is called
 a slice. Is that correct?
No. 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. The "D Slices" article is great for explaining how things work but does not use the official terminology. Per the official terminology, T[] is a dynamic array regardless of what memory it refers to. Assuming that it's non-null, it _does_ refer to a slice of memory, and a number of folks follow the article and call T[] a slice and refer to the GC-allocated memory that a T[] usually refers to as the dynamic array, but officially, T[] is the dynamic array, and the memory it refers to has no special name. It's just a block of memory that is usually GC-allocated, but it could be malloced or be a slice of a static array or any other type of memory (since you can create a dynamic array from pointers), and its semantics don't change based on what type of memory backs it. I gather that the author chose to refer to the GC-allocated block of memory as the dynamic array because of how the term dynamic array is sometimes used elsewhere in computer science, but as far as D is concerned, T[] is a dynamic array regardless of what memory it refers to, and personally, I think that focusing on the GC-allocated memory block as being the dynamic array causes confusion when dealing with dynamic arrays that refer to non-GC-allocated memory, since the semantics are identical regardless of what memory backs the array (it's just that if the array does not refer to a slice of GC-allocated memory, the capacity is always 0, guaranteed that appending will reallocate instead of it just being a possibility), but too many folks tend to think of them as being different. A dynamic array that refers to non-GC-allocated memory is really the same thing as one that is GC-allocated except that when you slice non-GC-allocated memory to create a dynamic array, you then need to be aware of how to manage the lifetime of that memory so that no dynamic array refering to it outlives it (just like you'd have to do with a pointer to non-GC-allocated memory). But dynamic arrays never manage their own memory. It's just that the GC does the managing by default and will reallocate the memory backing a dynamic array if an operation can't be done in-place. - Jonathan M Davis
Dec 29 2017
parent reply Tony <tonytdominguez aol.com> writes:
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
Dec 30 2017
next sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
On 12/30/17 8:57 PM, Tony wrote:
 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.
As stated in the slices article, I think of them as separate -- the slice is the public type that is used to operate on dynamic arrays, the dynamic array is a nameless type that only exists in the runtime. It helped me immensely when rewriting the array runtime to think of it that way. All the feedback I received when publishing the article was along the lines of "Wow, thinking of it that way helps a lot", so I think it's a good mental model. But in terms of D types, the slice *is* the dynamic array type, it behaves in all the ways you would expect a dynamic array type to behave. The only difference is that a slice does not own the memory it references. Normally you would consider a dynamic array to own its memory (i.e. be responsible for allocation and destruction). Because we have the GC, ownership can be fuzzy.
 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).
The question really is, what is the name of the type T[]? If you give it a different name depending on how it was created, then you have all sorts of confusion. In fact, there was a proposal by Walter and Andrei a long long time ago to have a type T[new] which would be the dynamic array type, and T[] be the slice type. This failed, because in Andrei's words, "Explaining two very similar but subtly different types to newcomers is excruciatingly difficult." IMO, T[] is a slice, because it may not be GC-backed dynamic array data underneath. Some people prefer to think of it as a dynamic array, because you can use it like a dynamic array no matter what it points at. Either way works, and fits the implementation. It's really a matter of preference. -Steve
Dec 31 2017
prev sibling parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Dec 31 2017
parent reply Tony <tonytdominguez aol.com> writes:
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:"
Dec 31 2017
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Dec 31 2017
next sibling parent reply Tony <tonytdominguez aol.com> writes:
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. -----------------------------------------------------------------------
Dec 31 2017
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Dec 31 2017
parent reply Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Jan 02 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Jan 02 2018
parent reply =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
First, I'm in complete agreement with Steve on this. I wrote a response 
to you yesterday, which I decided to not send after counting to ten 
because despite being much more difficult, I see that your view can also 
be aggreable.

On 01/02/2018 10:02 AM, Jonathan M Davis wrote:
 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.
My view as well.
 And D
 "array slices" (the proper term IMO) are not the same.
Exactly!
 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.
As soon as we call it "dynamic array", I can't help but think "adding elements". Since GC is in the picture when that happens, it's essential to think GC when adding an element is involved. Further, evident from your description it's a "slice" until you add elements because the underlying memory e.g. can be a stack-allocated fixed-length array. For these reasons, the interface that the program is using is a "slice". Dynamic array is a different concept owned and implemented by the GC.
 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.
You seem to anchor your view of array slices on appending elements to them. I see them mainly as accessors into existing elements. Add to that the fact that a slice does not have instruments itself to manage its memory, it remains a slice for me. Again, dynamic array is a GC thing that works behind the scenes. I can understand your point of view but I find it more confusing.
 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,
Is there really such a thing? D's dynamic arrays sit on GC-allocated memory, no?
 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.
That description gives the false impression that there are non-GC-backed dynamic arrays as if e.g. they can grow into their larger stack space like std.experimental.allocator.StackFront provides. D's dynamic arrays are not like that at all.
 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,
What you're describing is a slice into manually managed dynamic array. As soon as you append to it, now there is a GC-owned dynamic array.
 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
Yes, it is hard 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
Of course dynamic arrays cannot be just the memory buffer. There is also the behavior that comes with it, one of which being appending.
 rather than T[]
 itself makes that misunderstanding worse
I've always disaggreed with this.
 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.
I completely agree that "array slice" would be better but I disagree that slice is an overused term. Array slices are the same concept as slices of elements of other container types.
 - Jonathan M Davis
Regarding your reference to how both the language and the spec use "dynamic array", given how much confusion can be on these concepts, I have no trouble accepting that the terms used in the language and the spec are somewhat arbitrary; they could have easily used "slice" at the time. So, no matter what terms they used, there would be some disagreement. In this case, you're one who is happy with the current terms in the language and the spec but I would be happy if they were changed because I think the current terms are confusing to people who are new to D. Ali
Jan 02 2018
parent reply Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
On Tuesday, January 02, 2018 10:37:17 Ali Çehreli via Digitalmars-d-learn 
wrote:
 As soon as we call it "dynamic array", I can't help but think "adding
 elements". Since GC is in the picture when that happens, it's essential
 to think GC when adding an element is involved.

 Further, evident from your description it's a "slice" until you add
 elements because the underlying memory e.g. can be a stack-allocated
 fixed-length array.

 For these reasons, the interface that the program is using is a "slice".
 Dynamic array is a different concept owned and implemented by the GC.
Except that from the standpoint of the API, T[] _is_ the dynamic array - just like std::vector is the dynamic array and not whatever its guts are - and the semantics are the same whether it's backed by the GC or by a static array or by malloc-ed memory or whatever. Appending works exactly the same. Reallocation works the same. None of that changes based on whether the dynamic array is backed by GC-allocated memory or not. It's just that the capacity is guaranteed to be 0 if it isn't GC-allocated and so the first append operation is guaranteed to reallocate. The semantics of T[] itself don't change regardless, and most code doesn't need to care one whit about what kind of memory backs the dynamic array. No matter what memory backed it to start with, you get the same appending semantics. You get the same semantics when accessing the data. You get the same semantics when passing the dynamic array around. None of that depends on what kind of memory the dynamic array is a slice of. T[] functions as a dynamic array regardless of what memory backed it to start with, and as such, I completely agree with the spec calling it the dynamic array. And as soon as you start talking about T[] not being a dynamic array, you get this weird situation where T[] has all of the operations and semantics of a dynamic array, but you're not calling it a dynamic array simply because it happens to be a slice of memory that wasn't GC-allocated. So, you have this type in the type system whose semantics don't care what memory currently backs it and where code will act on it identically whether it's GC-backed or not, but folks want to then act like it's something different and treat it differently just because it happens to not be GC-backed at the moment - and the same function could be called with both GC-backed and non-GC-backed dynamic arrays. The type and its semantics are the same regardless. Of course, understanding how and when reallocation occurs matters if you want to understand the exact semantics of copying a dynamic array around or when appending or reserve is going to result in a reallocation, but that doesn't necessitate calling the GC-managed buffer the dynamic array. It just requires understanding how it's the GC that manages capacity, reserve, and appending rather than the dynamic array itself. But the API is that of a dynamic array regardless. If it weren't, you couldn't append to T[] any more than you can append to an arbitrary range. As soon as you insist on calling them slices, you're basically talking about them as if they were simply ranges rather that than the container/range hybrid that they are. Regardless, the fact that they're a container/range hybrid is what makes this such a mess to understand. The semantics actually work fantastically if you understand them, but it sure makes understanding them annoyingly difficult. - Jonathan M Davis
Jan 02 2018
parent =?UTF-8?Q?Ali_=c3=87ehreli?= <acehreli yahoo.com> writes:
On 01/02/2018 11:17 AM, Jonathan M Davis wrote:
 On Tuesday, January 02, 2018 10:37:17 Ali Çehreli via Digitalmars-d-learn
 wrote:
 For these reasons, the interface that the program is using is a "slice".
 Dynamic array is a different concept owned and implemented by the GC.
Except that from the standpoint of the API, T[] _is_ the dynamic array - just like std::vector is the dynamic array and not whatever its guts
are - I understand your point but I think it's more confusing to call it a dynamic array in the following code: int[42] array; int[] firstHalf = array[0..$/2]; I find it simpler to see it as a slice of existing elements. In contrast, calling it a dynamic array would require explaining not to worry, no memory is being allocated; the dynamic array is backed by the stack. Not very different from calling it a slice and then explaining the GC involvement in the case of append.
 Regardless, the fact that they're a container/range hybrid is what makes
 this such a mess to understand. The semantics actually work 
fantastically if
 you understand them, but it sure makes understanding them annoyingly
 difficult.

 - Jonathan M Davis
Agreed. Ali
Jan 02 2018
prev sibling parent Seb <seb wilzba.ch> writes:
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!
Jan 01 2018
prev sibling parent reply Ivan Trombley <itrombley dot-borg.org> writes:
double[] D = [3.14159];

Can you guess what D is?  :D
Dec 30 2017
next sibling parent reply Tony <tonytdominguez aol.com> writes:
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"
Dec 30 2017
parent reply codephantom <me noyb.com> writes:
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.
Dec 30 2017
parent reply Tony <tonytdominguez aol.com> writes:
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?
Dec 30 2017
parent Jonathan M Davis <newsgroup.d jmdavisprog.com> writes:
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
Dec 31 2017
prev sibling parent Steven Schveighoffer <schveiguy yahoo.com> writes:
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
Dec 31 2017