digitalmars.D - Setting array length to 0 discards reserved allocation?
- Andrew Godfrey (24/24) Jul 24 2014 Is this a bug? Or am I misunderstanding
- safety0ff (6/8) Jul 24 2014 You need to use assumeSafeAppend before increasing the length
- Chris Cain (22/22) Jul 24 2014 See this post:
- Jonathan M Davis via Digitalmars-d (13/15) Jul 24 2014 It's not a bug. If it did it any other way, you'd have problems with arr...
- Andrew Godfrey (22/24) Jul 25 2014 Thank you, that was educational.
- H. S. Teoh via Digitalmars-d (8/29) Jul 25 2014 That's a very good idea. I think that would dispel a lot of
- Andrew Godfrey (41/81) Jul 26 2014 So I've been looking into this, and I've realized the 'arrays'
- Jakob Ovrum (9/11) Jul 26 2014 Yes, the reference documentation is pretty terrible with naming
- Jonathan M Davis (13/24) Jul 27 2014 As defined by the language, T[] is a dynamic array. As great as
- Jakob Ovrum (3/15) Jul 27 2014 Conflating both concepts with the same name is why the article
- Jonathan M Davis (18/33) Jul 27 2014 Except that no concepts are being conflated. T[] is the dynamic
- Andrew Godfrey (15/18) Jul 27 2014 Yes, they are. Consider again the sentence I quoted: "Slicing an
- Jakob Ovrum (13/31) Jul 27 2014 This very thread is a testament to the fact that no, it's not
- Jonathan M Davis (9/42) Jul 27 2014 The array article does a great job explaining a lot about D
- Andrew Godfrey (23/31) Jul 27 2014 Look:
- Jesse Phillips (7/12) Jul 28 2014 'i' is a "dynamic array" and contains a reference to a "block of
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (16/28) Jul 28 2014 I bet that terminology is from before the design of slices was finalized...
- Jonathan M Davis (29/42) Jul 28 2014 It's simple, D's dynamic arrays _never_ own their memory. It's
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (6/48) Jul 29 2014 You don't say anything below that does not work when I replace "dynamic
- Jonathan M Davis via Digitalmars-d (6/62) Jul 29 2014 Because they're the same thing as far as D is concerned.
- Andrew Godfrey (10/21) Jul 29 2014 I gave this a try, and overall it looks like an improvement, but
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (6/30) Jul 29 2014 IMO slice fits quite well for both. `b[1..3]` is a slice (or
- Andrew Godfrey (20/37) Jul 29 2014 That wasn't meant to be a motivating example.
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (3/41) Jul 29 2014 Playing the devil's advocate:
- Andrew Godfrey (10/22) Jul 29 2014 Let's try to explain why this:
- Andrew Godfrey (6/6) Jul 29 2014 fyi, here's what I have so far.
- Jonathan M Davis (34/40) Jul 29 2014 I'm completely opposed to changing the official terminology. Per
- Dominikus Dittes Scherkl (19/20) Jul 29 2014 Why?
- Jonathan M Davis (23/43) Jul 31 2014 The "other thing" is just a block of memory managed by the GC and
- Dominikus Dittes Scherkl (18/45) Aug 01 2014 Really?
- Andrew Godfrey (3/4) Jul 30 2014 Now that I've done this exercise I can answer more crisply:
- Jonathan M Davis (10/14) Jul 31 2014 So the fact that it slices rather than copies is enough to make
- Andrew Godfrey (24/24) Aug 01 2014 Going through other .dd files, I found an error in expression.dd.
- Andrew Godfrey (4/4) Aug 01 2014 Pull request:
- Andrew Godfrey (3/28) Aug 01 2014 Rereading this, the original text did say "refers to". So calling
- Chris Cain (25/50) Aug 01 2014 I think the docs might can be cleared up in this regard, but from
- Andrew Godfrey (8/65) Aug 01 2014 Yes, I was a bit terse in my previous retraction (was low on
- Andrew Godfrey (7/7) Aug 11 2014 Reminder: The PR is ready for review:
- Dominikus Dittes Scherkl (7/14) Aug 11 2014 Very good.
- ketmar via Digitalmars-d (4/4) Aug 11 2014 On Mon, 11 Aug 2014 07:04:41 +0000
- Andrew Godfrey (16/21) Aug 13 2014 Thanks for adding your opinion - it's good to see more support
- Andrew agodfrey (2/2) Aug 17 2014 I've broken out the less controversial fixes into a separate PR:
- ketmar via Digitalmars-d (21/24) Aug 17 2014 On Thu, 14 Aug 2014 06:46:40 +0000
- Andrew Godfrey (22/54) Aug 19 2014 Maybe. But consider that if "a" was a class and "~=" was instead
- ketmar via Digitalmars-d (17/18) Aug 19 2014 yes. but passing null class will not allow to call it's methods, and
- Andrew Godfrey (12/37) Aug 20 2014 Well, this is just one case of a general confusion that classes
- ketmar via Digitalmars-d (6/6) Aug 20 2014 On Thu, 21 Aug 2014 03:24:35 +0000
- Andrew Godfrey (8/17) Aug 21 2014 Yeah, you have a point. "slice view" sounds odd, and I suppose
- ketmar via Digitalmars-d (4/8) Aug 21 2014 i agree, i just took the first words that came into my head. ;-)
- ketmar via Digitalmars-d (6/6) Aug 20 2014 On Thu, 21 Aug 2014 06:53:32 +0300
- ketmar via Digitalmars-d (12/12) Aug 17 2014 On Sun, 17 Aug 2014 10:32:51 +0300
- Steven Schveighoffer (21/28) Sep 15 2014 Sorry to be chiming in late on this.
- deadalnix (2/2) Sep 15 2014 We already are suing slices. We are creating the confusion by
- monarch_dodra (5/7) Sep 16 2014 IMO, the term "slice" is not necessarily different, but rather, a
- John Colvin (10/34) Jul 29 2014 You can look at it like this: There are no builtin dynamic arrays
- Gary Willoughby (7/15) Jul 25 2014 Instead of using the old library link (http://dlang.org/phobos/)
- Wyatt (5/7) Jul 25 2014 We are? Please, no. Holding the PHP doc comments up as an
- Andrei Alexandrescu (3/12) Jul 25 2014 Why? I don't have much context but a few people I talked to were positiv...
- Brad Anderson (8/24) Jul 25 2014 They are hit or miss. Sometimes you'll find exactly what you need
- H. S. Teoh via Digitalmars-d (7/30) Jul 25 2014 I'd suggest vetting user comments before posting them on the docs page,
- Wyatt (18/34) Jul 25 2014 I've written about this before, but here's the summary:
- Jonathan M Davis (5/17) Jul 25 2014 Agreed. I find the idea of having the official docs cluttered
- Dicebot (5/8) Jul 25 2014 You have not been reading latest discussions about it carefully
- Gary Willoughby (5/13) Jul 26 2014 So it's pretty much a consensus that it's a bad idea. I kinda
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (8/11) Jul 26 2014 I find the php comments useful when I have to use the docs. It
- "Marc =?UTF-8?B?U2Now7x0eiI=?= <schuetzm gmx.net> (5/16) Jul 27 2014 Sure, it could be used as a lightweight bugtracker. But them,
- "Ola Fosheim =?UTF-8?B?R3LDuHN0YWQi?= (13/16) Jul 27 2014 I also find example code useful sometimes when a function/feature
Is this a bug? Or am I misunderstanding something? import std.stdio, std.string; import std.array; unittest { int[] a; a.reserve(10); a.length++; int *p = &(a[0]); a.length++; // Increase size. Shouldn't reallocate. int *p2 = &(a[0]); assert(p == p2); // And indeed it didn't. // So sometime later, we want to reuse the allocation. We 'clear' it: a.length = 0; // ... and later start using it... a.length++; int *q = &a[0]; assert(p == q, format("p: %s; q: %s", p, q)); // FAILS! (on dmd 2.065.0) Why? Apparently, setting length to 0 caused it to free the // reserved allocation? }
Jul 24 2014
On Thursday, 24 July 2014 at 23:30:13 UTC, Andrew Godfrey wrote:Is this a bug? Or am I misunderstanding something?You need to use assumeSafeAppend before increasing the length again to avoid allocating new storage. The runtime doesn't know that `a` is the only reference to that array, so increasing the length causes an allocation to avoid stomping on data.
Jul 24 2014
See this post: http://forum.dlang.org/thread/shpcpmwvphbyaumxghsd forum.dlang.org My response in that thread: ---- The reason is simple, observe: auto arr = [1,2,3] It is safe if you append 4 to that. auto arr = [1,2,3,4] auto other = arr[]; arr.length = 2; It is *not* safe to append 5 to arr here, because doing so would change other to [1,2,5,4] which is (probably) not what you want (or, at least, you haven't made it explicit that you're okay with this behavior). Since slices are unaware of whether other views on memory exist, they must always reallocate if they've been shrunk to avoid the possibility of overwriting existing elements in other views of the array. When you use "assumeSafeAppend", you are guaranteeing that either no other views exist, or if they do exist that you don't care if they are overwritten. Take note that the second case is *really bad* if your element type is immutable, for obvious reasons. ----
Jul 24 2014
On Thu, 24 Jul 2014 23:30:11 +0000 Andrew Godfrey via Digitalmars-d <digitalmars-d puremagic.com> wrote:Is this a bug? Or am I misunderstanding something?It's not a bug. If it did it any other way, you'd have problems with arrays stomping on each others memory. The underlying data structure keeps track of the farthest point in the block which an array has been expanded to, but it doesn't keep track of what arrays exist that point to it, so it can't know which ones point where. So, it has no way of knowing that the slice whose length you're setting to 0 is the only slice. assumeSafeAppend is used to fix that problem, but you have to be sure that it _is_ safe to append to that array without stomping on other arrays, or you're going to have problems. You really should read this article: http://dlang.org/d-array-article.html - Jonathan M Davis
Jul 24 2014
On Friday, 25 July 2014 at 04:38:40 UTC, Jonathan M Davis via Digitalmars-d wrote:You really should read this article: http://dlang.org/d-array-article.htmlThank you, that was educational. What I needed to read was that "A slice does not own the array, it references the array." - which I knew, but I hadn't internalized that even when a dynamic array is a private member, it is accessed via a slice and the runtime is not aware when there's a 1-to-1 correspondence between the two. The documentation could help a bit more. I'm game to try to make a pull request for this, but I'm wondering if the library docs can actually point to the article? More feasibly, I'm thinking: Both the documentation for length() (http://dlang.org/arrays) and reserve() (http://dlang.org/phobos/std_array.html) should at least mention assumeSafeAppend. An example similar to what I posted may also be worthwhile. (As I understand it from the article, the problem is that reducing 'length' also reduces 'used', whereas in this case I really want that slice to continue to own the entire reserved amount.)
Jul 25 2014
On Fri, Jul 25, 2014 at 03:07:53PM +0000, Andrew Godfrey via Digitalmars-d wrote:On Friday, 25 July 2014 at 04:38:40 UTC, Jonathan M Davis via Digitalmars-d wrote:That's a very good idea. I think that would dispel a lot of misconceptions that newcomers might have.You really should read this article: http://dlang.org/d-array-article.htmlThank you, that was educational. What I needed to read was that "A slice does not own the array, it references the array." - which I knew, but I hadn't internalized that even when a dynamic array is a private member, it is accessed via a slice and the runtime is not aware when there's a 1-to-1 correspondence between the two. The documentation could help a bit more. I'm game to try to make a pull request for this, but I'm wondering if the library docs can actually point to the article?More feasibly, I'm thinking: Both the documentation for length() (http://dlang.org/arrays) and reserve() (http://dlang.org/phobos/std_array.html) should at least mention assumeSafeAppend. An example similar to what I posted may also be worthwhile.[...] Yes, please submit a PR for this. T -- I see that you JS got Bach.
Jul 25 2014
On Friday, 25 July 2014 at 15:55:50 UTC, H. S. Teoh via Digitalmars-d wrote:On Fri, Jul 25, 2014 at 03:07:53PM +0000, Andrew Godfrey via Digitalmars-d wrote:So I've been looking into this, and I've realized the 'arrays' page is actually inconsistent. (http://dlang.org/arrays). Instead of spending time on a big update, I'll outline a proposal here. This page generally uses the term "array" to mean the slice, and "array data" to mean the allocated data that a slice currently refers to. (In contrast, the handy article calls these "slice" and "dynamic array" respectively). For example:On Friday, 25 July 2014 at 04:38:40 UTC, Jonathan M Davis via Digitalmars-d wrote:That's a very good idea. I think that would dispel a lot of misconceptions that newcomers might have.You really should read this article: http://dlang.org/d-array-article.htmlThank you, that was educational. What I needed to read was that "A slice does not own the array, it references the array." - which I knew, but I hadn't internalized that even when a dynamic array is a private member, it is accessed via a slice and the runtime is not aware when there's a 1-to-1 correspondence between the two. The documentation could help a bit more. I'm game to try to make a pull request for this, but I'm wondering if the library docs can actually point to the article?More feasibly, I'm thinking: Both the documentation for length() (http://dlang.org/arrays) and reserve() (http://dlang.org/phobos/std_array.html) should at least mention assumeSafeAppend. An example similar to what I posted may also be worthwhile.[...] Yes, please submit a PR for this.Dynamic Arrays int[] a;Dynamic arrays consist of a length and a pointer to the array data. Multiple > dynamic arrays can share all or parts of the array data.Problems start early on:SlicingSlicing an array means to specify a subarray of it. An array slice does not copy the data, it is only another reference to it.By this page's terminology, this should actually say something like this: "slicing an array means to specify a subarray of that array's current array data". e.g. Causing the first 'array' (slice) to grow would dissociate the slices from each other. Because the term "slice" is so foreign, I sympathize with how the term was avoided to start with. But the fact is that a dynamic array declaration creates two separate things, and so I'd propose to give them reliable names at the earliest. So: Immediately after the section that introduces dynamic arrays, I would then put the section on slices, and rather than describing a slice as a "subarray", I would introduce it as an important part of the workings of a dynamic array. So I'm thinking the first example of a slice should be a simplification of the article's example: int[] a = new int[5]; // A new dynamic array, with slice 'a' pointing to it. int[] b = a[]; // We now have two slices pointing to one dynamic array. a[1] = 42; assert(b[1] == 42); // Demonstrating the point Thereafter can come sub-slice examples and so on. Does this make sense?
Jul 26 2014
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 ;)
Jul 26 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:As defined by the language, T[] is a dynamic array. As great as the article is, it was wrong in its use of the terminology, and that's what's caused a lot of the confusion and resulted in arguments over the difference between a dynamic array and a slice (there really isn't any). IIRC, both Walter and Andrei stated in that discussion that T[] is a dynamic array as far as D is concerned and that's not going to change. The article really should be updated to reflect the correct terminology. As far as D is concerned a slice and a dynamic array are the same thing when it comes to arrays. They're just different names for T[], and trying to treat them as different just causes confusion. - Jonathan M DavisThereafter 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 ;)
Jul 27 2014
On Sunday, 27 July 2014 at 08:49:43 UTC, Jonathan M Davis wrote:As defined by the language, T[] is a dynamic array. As great as the article is, it was wrong in its use of the terminology, and that's what's caused a lot of the confusion and resulted in arguments over the difference between a dynamic array and a slice (there really isn't any). IIRC, both Walter and Andrei stated in that discussion that T[] is a dynamic array as far as D is concerned and that's not going to change. The article really should be updated to reflect the correct terminology. As far as D is concerned a slice and a dynamic array are the same thing when it comes to arrays. They're just different names for T[], and trying to treat them as different just causes confusion.Conflating both concepts with the same name is why the article was so dearly needed in the first place.
Jul 27 2014
On Sunday, 27 July 2014 at 09:10:26 UTC, Jakob Ovrum wrote:On Sunday, 27 July 2014 at 08:49:43 UTC, Jonathan M Davis wrote:Except that no concepts are being conflated. T[] is the dynamic array. There's a block of memory managed by the GC underneath, but it's completely hidden from the programmer. It is _not_ the dynamic array. It's just a block of memory managed by the GC which is used to manage the memory for dynamic arrays, and it has a completely different type from T[]. It's not even an array in the D sense. The block of memory is referred to by a pointer, not a D array. It's talk of "which array" owns the memory and the like which causes confusion, and talking about the GC-managed block of memory as being the dynamic array and the T[] that the programmer sees as being the slice is just plain wrong. The T[] is both a slice and a dynamic array (because they're the same thing), whereas the block of memory is neither. I think that the fact that the article tried to call the underlying block of memory a dynamic array has caused a lot of unnecessary confusion. - Jonathan M DavisAs defined by the language, T[] is a dynamic array. As great as the article is, it was wrong in its use of the terminology, and that's what's caused a lot of the confusion and resulted in arguments over the difference between a dynamic array and a slice (there really isn't any). IIRC, both Walter and Andrei stated in that discussion that T[] is a dynamic array as far as D is concerned and that's not going to change. The article really should be updated to reflect the correct terminology. As far as D is concerned a slice and a dynamic array are the same thing when it comes to arrays. They're just different names for T[], and trying to treat them as different just causes confusion.Conflating both concepts with the same name is why the article was so dearly needed in the first place.
Jul 27 2014
Yes, they are. Consider again the sentence I quoted: "Slicing an array means to specify a subarray of it." The word "it" is wrong; for it to be correct, it needs to refer to the underlying memory block, not the "array". This was the original cause of my confusion, I believe - it led me to think that "T[] is a dynamic array" (by which I mean a concept I understand well from other languages) but in fact, D has redefined the term "dynamic array" to mean something quite different. So, not only is "T[]" NOT the concept I thought it was, what it IS apparently goes by the same name as the concept I had confused it with! For the sake of increased adoption of D, I beg you to reconsider. I am not exaggerating - for a while there I thought I was looking at a huge red flag, and if I didn't already appreciate other strengths of D, I would have stopped there.Conflating both concepts with the same name is why the article was so dearly needed in the first place.Except that no concepts are being conflated.
Jul 27 2014
On Sunday, 27 July 2014 at 12:03:05 UTC, Jonathan M Davis wrote:Except that no concepts are being conflated. T[] is the dynamic array. There's a block of memory managed by the GC underneath, but it's completely hidden from the programmer. It is _not_ the dynamic array. It's just a block of memory managed by the GC which is used to manage the memory for dynamic arrays, and it has a completely different type from T[]. It's not even an array in the D sense. The block of memory is referred to by a pointer, not a D array. It's talk of "which array" owns the memory and the like which causes confusion, and talking about the GC-managed block of memory as being the dynamic array and the T[] that the programmer sees as being the slice is just plain wrong. The T[] is both a slice and a dynamic array (because they're the same thing), whereas the block of memory is neither. I think that the fact that the article tried to call the underlying block of memory a dynamic array has caused a lot of unnecessary confusion. - Jonathan M DavisThis very thread is a testament to the fact that no, it's not completely hidden, and it is the conflation that causes confusion, and clarity only comes when the two concepts are explained separately. This matches my experience when I teach about D's arrays on IRC too - people generally feel enlightened after reading the array article. It's debatable whether hamfisting dynamic array capabilities onto a simple slice type was a good idea or not (T[new], anyone?), but we should be as clear with the current situation as possible. Pretending there isn't a problem is ignoring the cries of D newbies everywhere. Please stop.
Jul 27 2014
On Sunday, 27 July 2014 at 13:03:13 UTC, Jakob Ovrum wrote:On Sunday, 27 July 2014 at 12:03:05 UTC, Jonathan M Davis wrote:The array article does a great job explaining a lot about D arrays, and it definitely has helped people understand them. But it uses the wrong terminology, and that's my point. In D, T[] is a dynamic array and a slice. As far as D is concerned, there is no difference. T[] normally refers to a block of memory that the GC manages, but that block of memory is not typed as a dynamic array. And that's where the article gets it wrong. - Jonathan M DavisExcept that no concepts are being conflated. T[] is the dynamic array. There's a block of memory managed by the GC underneath, but it's completely hidden from the programmer. It is _not_ the dynamic array. It's just a block of memory managed by the GC which is used to manage the memory for dynamic arrays, and it has a completely different type from T[]. It's not even an array in the D sense. The block of memory is referred to by a pointer, not a D array. It's talk of "which array" owns the memory and the like which causes confusion, and talking about the GC-managed block of memory as being the dynamic array and the T[] that the programmer sees as being the slice is just plain wrong. The T[] is both a slice and a dynamic array (because they're the same thing), whereas the block of memory is neither. I think that the fact that the article tried to call the underlying block of memory a dynamic array has caused a lot of unnecessary confusion. - Jonathan M DavisThis very thread is a testament to the fact that no, it's not completely hidden, and it is the conflation that causes confusion, and clarity only comes when the two concepts are explained separately. This matches my experience when I teach about D's arrays on IRC too - people generally feel enlightened after reading the array article. It's debatable whether hamfisting dynamic array capabilities onto a simple slice type was a good idea or not (T[new], anyone?), but we should be as clear with the current situation as possible. Pretending there isn't a problem is ignoring the cries of D newbies everywhere. Please stop.
Jul 27 2014
The array article does a great job explaining a lot about D arrays, and it definitely has helped people understand them. But it uses the wrong terminology, and that's my point. In D, T[] is a dynamic array and a slice. As far as D is concerned, there is no difference. T[] normally refers to a block of memory that the GC manages, but that block of memory is not typed as a dynamic array. And that's where the article gets it wrong.Look: auto c = new MyClass(); The D spec calls c "a reference to a class instance". This is good terminology because there can be a many-to-one relationship between references and classes. In contrast, early object". This was a misguided attempt to hide the fact that there's a reference involved - a fact that cannot and should not be hidden. And the thing it refers to needs a name more specific than "a block of memory". Now: int[] i = new int[5]; For now let's call 'i' a "dynamic array" and the thing it refers to a "foobar". The point is still the same: As with object references, there can be a many-to-one relationship between "dynamic arrays" and "foobars", and attempts to hide that relationship (e.g. by not giving "foobar" a name more specific than "block of memory") are misguided. Furthermore, the concept we're calling a "foobar" here is usually called a "dynamic array" in other languages. So IMO D is making the same mistake as when people call c above "an object".
Jul 27 2014
On Sunday, 27 July 2014 at 18:52:55 UTC, Andrew Godfrey wrote:Now: int[] i = new int[5]; For now let's call 'i' a "dynamic array" and the thing it refers to a "foobar".'i' is a "dynamic array" and contains a reference to a "block of memory." Frankly I don't see how making the distinction at 'dynamic array' and 'slice' will help with the particular confusion. For example, in Go a slice stomps memory: http://he-the-great.livejournal.com/48672.html
Jul 28 2014
On 07/27/2014 01:49 AM, Jonathan M Davis wrote:As defined by the language, T[] is a dynamic array.I bet that terminology is from before the design of slices was finalized about four years ago.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.IIRC, both Walter and Andrei stated in that discussion that T[] is a dynamic array as far as D is concerned and that's not going to change.I would like to hear Andrei's and Walter's current opinions on the matter.The article really should be updated to reflect the correct terminology.It should stay as is to maintain sanity. :)As far as D is concerned a slice and a dynamic array are the same thing when it comes to arrays. They're just different names for T[], and trying to treat them as different just causes confusion.To me, treating them differently removes all the confusion.- Jonathan M DavisAli
Jul 28 2014
On Monday, 28 July 2014 at 22:29:04 UTC, Ali Çehreli wrote:On 07/27/2014 01:49 AM, Jonathan M Davis wrote:It's simple, D's dynamic arrays _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 dynamic array / slice is likely to be reallocated, but it's pretty irrelevant to the type itself. In your example, both a and b are dynamic arrays which are slices of the same underlying block of memory. It's a and b which are the dynamic arrays, 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 - dynamic arrays - 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 dynamic array 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 Davisdifference between a dynamic array and a slice (there reallyisn'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.
Jul 28 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:The array article uses terminology that removes confusion. AliOn 07/27/2014 01:49 AM, Jonathan M Davis wrote: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 Davisdifference between a dynamic array and a slice (there reallyisn'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.
Jul 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
Jul 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: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 bThereafter 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 ;)
Jul 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: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".On Saturday, 26 July 2014 at 23:06:02 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 bThereafter 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 ;)
Jul 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: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).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 bIMO 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".
Jul 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:Playing the devil's advocate: Yes, it does so by assigning a slice from `c` to a slice from `b`.On Tuesday, 29 July 2014 at 07:46:34 UTC, Andrew Godfrey wrote: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).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 bIMO 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".
Jul 29 2014
On Tuesday, 29 July 2014 at 20:06:28 UTC, Marc Schütz wrote: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.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`.
Jul 29 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
Jul 29 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/463b5656151616e2a164ad414cf2bd61d1b84bebI'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
Jul 29 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).
Jul 29 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: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 DavisI'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).
Jul 31 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: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".[...] 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.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.
Aug 01 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.
Jul 30 2014
On Wednesday, 30 July 2014 at 09:52:15 UTC, Andrew Godfrey wrote: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 DavisWhat 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.
Jul 31 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.
Aug 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.
Aug 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.
Aug 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.
Aug 01 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: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.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.
Aug 01 2014
Reminder: The PR is ready for review: https://github.com/D-Programming-Language/dlang.org/pull/623 Jonathan has summarized his position in the commments. What do the rest of you think? H. S. Teoh, Jakob, Ali, Marc, Dominikus, Chris - your impression of whether this clears up the confusion would help round out the feedback.
Aug 11 2014
On Monday, 11 August 2014 at 07:04:42 UTC, Andrew Godfrey wrote:Reminder: The PR is ready for review: https://github.com/D-Programming-Language/dlang.org/pull/623 Jonathan has summarized his position in the commments. What do the rest of you think? H. S. Teoh, Jakob, Ali, Marc, Dominikus, Chris - your impression of whether this clears up the confusion would help round out the feedback.Very good. Most of the documentation becomes imediately much more intuitive and instructive. Beside some typos (at one place I saw an uppercase C where a valiable "c" was menat, in another place a variable c is refered but only b was declared), I'm very much in favor of those changes.
Aug 11 2014
On Mon, 11 Aug 2014 07:04:41 +0000 Andrew Godfrey via Digitalmars-d <digitalmars-d puremagic.com> wrote: Jonathan is right. what this PR does is changing one (somewhat confusing) terminology to another, even more confusing one.
Aug 11 2014
On Monday, 11 August 2014 at 19:43:26 UTC, ketmar via Digitalmars-d wrote:On Mon, 11 Aug 2014 07:04:41 +0000 Andrew Godfrey via Digitalmars-d <digitalmars-d puremagic.com> wrote: Jonathan is right. what this PR does is changing one (somewhat confusing) terminology to another, even more confusing one.Thanks for adding your opinion - it's good to see more support for Jonathan's side. Don't think I'm being flippant, but I have trouble interpreting such feedback, because D's dynamic array semantics ARE complicated. So if I happened to succeed in making a clear, accurate description of how it works, I would expect it to take many readers from an inaccurate, overly-simplistic understanding to an accurate (but unfortunately more complex) one. I have cause to question this - the docs themselves had some important misunderstandings - clear errors. It's possible that this was cruft and the authors never had those misunderstandings themselves - but some of their readers certainly did.
Aug 13 2014
I've broken out the less controversial fixes into a separate PR: https://github.com/D-Programming-Language/dlang.org/pull/629
Aug 17 2014
On Thu, 14 Aug 2014 06:46:40 +0000 Andrew Godfrey via Digitalmars-d <digitalmars-d puremagic.com> wrote: sorry for the late answer.Don't think I'm being flippant, but I have trouble interpreting=20 such feedback, because D's dynamic array semantics ARE=20 complicated.and it will be even more complicated if we will rename 'em to 'array references'. i completely agree that D dynarray docs can be made clearer and i appreciate any efforts which makes docs better. i'm just against 'reference' term -- seems that i'm from that minority that becomes immediately confused when reading 'array reference'. what i expect from 'reference' is that this code works: void foo (int[] a) { a ~=3D 42; } ... int[] arr; arr ~=3D 666; foo(arr); assert(arr.length =3D=3D 1 && arr[0] =3D=3D 42); but it doesn't. so arrays clearly aren't 'references' (as 'reference', to my opinion, should keep 'pass by reference' semantics in this case). so maybe we should coin some new word to describe dynarrays in D.
Aug 17 2014
On Sunday, 17 August 2014 at 07:33:01 UTC, ketmar via Digitalmars-d wrote:On Thu, 14 Aug 2014 06:46:40 +0000 Andrew Godfrey via Digitalmars-d <digitalmars-d puremagic.com> wrote: sorry for the late answer.Maybe. But consider that if "a" was a class and "~=" was instead "=", you would have the same confusion. As in: void foo(MyClass a) { a = new MyClass; } In either case, we are "passing a reference by value". So operations on the referent affect the passed object/array, but operations on the reference do not. The further surprise is caused because concatenation affects the _reference_. In fact it doesn't affect the referent at all! Good example. Consider that this works: void foo (int[] a) { a[0] = 42; } int[] arr; arr ~= 666; foo(arr); assert(arr.length == 1 && arr[0] == 42);Don't think I'm being flippant, but I have trouble interpreting such feedback, because D's dynamic array semantics ARE complicated.and it will be even more complicated if we will rename 'em to 'array references'. i completely agree that D dynarray docs can be made clearer and i appreciate any efforts which makes docs better. i'm just against 'reference' term -- seems that i'm from that minority that becomes immediately confused when reading 'array reference'. what i expect from 'reference' is that this code works: void foo (int[] a) { a ~= 42; } ... int[] arr; arr ~= 666; foo(arr); assert(arr.length == 2 && arr[1] == 42); but it doesn't. so arrays clearly aren't 'references' (as 'reference', to my opinion, should keep 'pass by reference' semantics in this case). so maybe we should coin some new word to describe dynarrays in D.
Aug 19 2014
On Tue, 19 Aug 2014 23:58:57 +0000 Andrew Godfrey via Digitalmars-d <digitalmars-d puremagic.com> wrote:In either case, we are "passing a reference by value".yes. but passing null class will not allow to call it's methods, and passing null array will. i.e. auto foo (MyClass a) { return a.length; } will crash if length is not a static method (and it can't be static) and foo is called like this: foo(null). but the same call will work for 'int[]'. so user can assume that 'int[]' is something similar to class, and it's perfectly ok to use int[] methods, and '~=3D' is just the overloaded method, which should change contents of passed dynarray. again, overloaded '~=3D' will work for class (more or less), but will inevitably fail (i.e. will not change passed arg) for dynarray. and it's clear that 'a =3D new MyClass()' creates new object. and it's not clear at all that 'a ~=3D 42' creates new object too. it's counterintuitive. that's why i think that we need new term.
Aug 19 2014
On Wednesday, 20 August 2014 at 00:13:32 UTC, ketmar via Digitalmars-d wrote:On Tue, 19 Aug 2014 23:58:57 +0000 Andrew Godfrey via Digitalmars-d <digitalmars-d puremagic.com> wrote:Well, this is just one case of a general confusion that classes and dynamic arrays already share, by virtue of having hidden reference semantics (i.e. the "." operator dereferences in some cases and not in others, sometimes surprising novices). You can see this in the existing array doc (http://dlang.org/arrays) where it describes the "sizeof" property for dynamic arrays. sizeof returns the size of the "dynamic array reference". A novice might expect it to return the size of the pointed-to array, to act more like the static-array case.In either case, we are "passing a reference by value".yes. but passing null class will not allow to call it's methods, and passing null array will. i.e. auto foo (MyClass a) { return a.length; } will crash if length is not a static method (and it can't be static) and foo is called like this: foo(null). but the same call will work for 'int[]'. so user can assume that 'int[]' is something similar to class, and it's perfectly ok to use int[] methods, and '~=' is just the overloaded method, which should change contents of passed dynarray. again, overloaded '~=' will work for class (more or less), but will inevitably fail (i.e. will not change passed arg) for dynarray. and it's clear that 'a = new MyClass()' creates new object. and it's not clear at all that 'a ~= 42' creates new object too. it's counterintuitive. that's why i think that we need new term.
Aug 20 2014
On Thu, 21 Aug 2014 03:24:35 +0000 Andrew Godfrey via Digitalmars-d <digitalmars-d puremagic.com> wrote: maybe just call that "slice views"? ;-) really, uncommon term will (at least it should ;-) make user to read about that "slice views", and "reference" is something like "ah, i know what references is, let's start coding now!"
Aug 20 2014
On Thursday, 21 August 2014 at 03:53:42 UTC, ketmar via Digitalmars-d wrote:On Thu, 21 Aug 2014 03:24:35 +0000 Andrew Godfrey via Digitalmars-d <digitalmars-d puremagic.com> wrote: maybe just call that "slice views"? ;-) really, uncommon term will (at least it should ;-) make user to read about that "slice views", and "reference" is something like "ah, i know what references is, let's start coding now!"Yeah, you have a point. "slice view" sounds odd, and I suppose all this is the background to why some parts of the docs use the term "slice" for this. Maybe I should have another look at that - maybe introducing "slice" first and the "slice operator" later, can avoid confusion sufficiently.
Aug 21 2014
On Thu, 21 Aug 2014 07:23:34 +0000 Andrew Godfrey via Digitalmars-d <digitalmars-d puremagic.com> wrote:"slice view" sounds oddi agree, i just took the first words that came into my head. ;-)Maybe I should have another look at that - maybe introducing=20 "slice" first and the "slice operator" later, can avoid confusion=20 sufficiently.sound reasonable for me.
Aug 21 2014
On Thu, 21 Aug 2014 06:53:32 +0300 ketmar via Digitalmars-d <digitalmars-d puremagic.com> wrote: offtopic: damn it! i will read my messages before posting. i will read my messages before posting. i will read my messages before posting. i will... who i'm trying to cheat?! too bad that we can't edit messages after posting.
Aug 20 2014
On Sun, 17 Aug 2014 10:32:51 +0300 ketmar via Digitalmars-d <digitalmars-d puremagic.com> wrote: sorry, i meant THIS code: =20 void foo (int[] a) { a ~=3D 42; } ... int[] arr; arr ~=3D 666; foo(arr); assert(arr.length =3D=3D 2 && arr[1] =3D=3D 42);
Aug 17 2014
On Mon, 11 Aug 2014 03:04:41 -0400, Andrew Godfrey <x y.com> wrote:Reminder: The PR is ready for review: https://github.com/D-Programming-Language/dlang.org/pull/623 Jonathan has summarized his position in the commments. What do the rest of you think? H. S. Teoh, Jakob, Ali, Marc, Dominikus, Chris - your impression of whether this clears up the confusion would help round out the feedback.Sorry to be chiming in late on this. As the author of the article, I stand by my terminology, even if it's not "official." In fact, when I was writing the article, I was struggling to describe how arrays worked until I stumbled into that description, and then it all clicked pretty well. This issue has come up before, and I can't remember what the result was, but I am not severely attached to the terminology if it hurts the documentation of D (In other words, I'm willing to allow a pull request to the article on dlang's site if it is what people want). As I recall, I was in favor of changing the official definition (though not the advocate of it), but most were not. I think the definition of dynamic array as most languages define it, and dynamic array as D defines it, are not exactly at odds with each other, but the differences are significant. What is needed is a nice term for "reference to a chunk of data." I thought slice fit that bill nicely, but I can see how it would be confusing. The fact that slices act sort of like dynamic arrays, even though they may not even point at arrays at all, is a very awkward definition. It would be like calling all C pointers arrays. -Steve
Sep 15 2014
We already are suing slices. We are creating the confusion by pretending there is 2 different concepts when there is only one.
Sep 15 2014
On Tuesday, 16 September 2014 at 01:32:55 UTC, deadalnix wrote:We already are suing slices. We are creating the confusion by pretending there is 2 different concepts when there is only one.IMO, the term "slice" is not necessarily different, but rather, a *refinement* of the "dynamic array" term. Without changing any formal definition, just use the term slice whenever you can, and 95% of the ambiguity goes away.
Sep 16 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: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.On Saturday, 26 July 2014 at 23:06:02 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 bThereafter 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 ;)
Jul 29 2014
On Friday, 25 July 2014 at 15:07:55 UTC, Andrew Godfrey wrote:The documentation could help a bit more. I'm game to try to make a pull request for this, but I'm wondering if the library docs can actually point to the article? More feasibly, I'm thinking: Both the documentation for length() (http://dlang.org/arrays) and reserve() (http://dlang.org/phobos/std_array.html) should at least mention assumeSafeAppend. An example similar to what I posted may also be worthwhile.Instead of using the old library link (http://dlang.org/phobos/) use http://dlang.org/library/ instead. This way you can go to http://dlang.org/library/std/array.html and in the discuss section at the bottom make comments. The D community is hoping those discussion sections start being used in the same way the PHP documentation is used.
Jul 25 2014
On Friday, 25 July 2014 at 15:59:18 UTC, Gary Willoughby wrote:The D community is hoping those discussion sections start being used in the same way the PHP documentation is used.We are? Please, no. Holding the PHP doc comments up as an example of a positive thing is alternately alternately hilarious and terrifying. -Wyatt
Jul 25 2014
"Wyatt" <wyatt.epp gmail.com> wrote:On Friday, 25 July 2014 at 15:59:18 UTC, Gary Willoughby wrote:Why? I don't have much context but a few people I talked to were positive about the community contribution to php docs. -- AndreiThe D community is hoping those discussion sections start being used in the same way the PHP documentation is used.We are? Please, no. Holding the PHP doc comments up as an example of a positive thing is alternately alternately hilarious and terrifying. -Wyatt
Jul 25 2014
On Friday, 25 July 2014 at 17:32:38 UTC, Andrei Alexandrescu wrote:"Wyatt" <wyatt.epp gmail.com> wrote:They are hit or miss. Sometimes you'll find exactly what you need and sometimes you'll find terrible misinformation. I suspect this our community will fair better than PHP has here but there is still that risk. I think it's worth a shot and if it becomes a problem the user comments can just be removed.On Friday, 25 July 2014 at 15:59:18 UTC, Gary Willoughby wrote:Why? I don't have much context but a few people I talked to were positive about the community contribution to php docs. -- AndreiThe D community is hoping those discussion sections start being used in the same way the PHP documentation is used.We are? Please, no. Holding the PHP doc comments up as an example of a positive thing is alternately alternately hilarious and terrifying. -Wyatt
Jul 25 2014
On Fri, Jul 25, 2014 at 05:37:24PM +0000, Brad Anderson via Digitalmars-d wrote:On Friday, 25 July 2014 at 17:32:38 UTC, Andrei Alexandrescu wrote:I'd suggest vetting user comments before posting them on the docs page, but that would mean requiring forumites to allocate yet more of their copious free time to the task. ;-) T -- Жил-был король когда-то, при нём блоха жила."Wyatt" <wyatt.epp gmail.com> wrote:They are hit or miss. Sometimes you'll find exactly what you need and sometimes you'll find terrible misinformation. I suspect this our community will fair better than PHP has here but there is still that risk. I think it's worth a shot and if it becomes a problem the user comments can just be removed.On Friday, 25 July 2014 at 15:59:18 UTC, Gary Willoughby wrote:Why? I don't have much context but a few people I talked to were positive about the community contribution to php docs. -- AndreiThe D community is hoping those discussion sections start being used in the same way the PHP documentation is used.We are? Please, no. Holding the PHP doc comments up as an example of a positive thing is alternately alternately hilarious and terrifying. -Wyatt
Jul 25 2014
On Friday, 25 July 2014 at 17:32:38 UTC, Andrei Alexandrescu wrote:"Wyatt" <wyatt.epp gmail.com> wrote:I've written about this before, but here's the summary: There will be a comment thread on every single function in the standard library where people will say whatever they want and we can't stop them ahead of time. - Anything they could possibly post there that's legitimately worth having would be better off canonised in the docs in the first place. - Any questions they ask would be better asked on D.learn. - Any other post may be subtly incorrect, previously correct, incredibly unsafe, correct with caveats, or a multitude of other shades of wrong. - Everything else is noise. We'd be better off wikifying the whole lot of it, and I don't say that lightly. At least then there's the possibility of it being clear what's changing and who is changing it. -WyattOn Friday, 25 July 2014 at 15:59:18 UTC, Gary Willoughby wrote:Why? I don't have much context but a few people I talked to were positive about the community contribution to php docs. -- AndreiThe D community is hoping those discussion sections start being used in the same way the PHP documentation is used.We are? Please, no. Holding the PHP doc comments up as an example of a positive thing is alternately alternately hilarious and terrifying. -Wyatt
Jul 25 2014
On Friday, 25 July 2014 at 19:08:07 UTC, Wyatt wrote:I've written about this before, but here's the summary: There will be a comment thread on every single function in the standard library where people will say whatever they want and we can't stop them ahead of time. - Anything they could possibly post there that's legitimately worth having would be better off canonised in the docs in the first place. - Any questions they ask would be better asked on D.learn. - Any other post may be subtly incorrect, previously correct, incredibly unsafe, correct with caveats, or a multitude of other shades of wrong. - Everything else is noise.Agreed. I find the idea of having the official docs cluttered with comments from literally anyone who could say anything (correct or not) to be a terrible idea. - Jonathan M Davis
Jul 25 2014
On Friday, 25 July 2014 at 17:32:38 UTC, Andrei Alexandrescu wrote:Why? I don't have much context but a few people I talked to were positive about the community contribution to php docs. -- AndreiYou have not been reading latest discussions about it carefully then ;) (I also think it is bad idea)
Jul 25 2014
On Saturday, 26 July 2014 at 01:48:11 UTC, Dicebot wrote:On Friday, 25 July 2014 at 17:32:38 UTC, Andrei Alexandrescu wrote:So it's pretty much a consensus that it's a bad idea. I kinda agree that *any* comment shouldn't be allowed. However there is great knowledge in the community that would be nice to capture somehow.Why? I don't have much context but a few people I talked to were positive about the community contribution to php docs. -- AndreiYou have not been reading latest discussions about it carefully then ;) (I also think it is bad idea)
Jul 26 2014
On Friday, 25 July 2014 at 17:32:38 UTC, Andrei Alexandrescu wrote:Why? I don't have much context but a few people I talked to were positive about the community contribution to php docs. -- AndreiI find the php comments useful when I have to use the docs. It isn't about correctness, it is about gotchas and potential work-arounds. No worse than stack overflow. There is noise, but it makes no difference at the bottom of the page. People are also more likely to comment there than submitting a formal complaint about errors in the docs.
Jul 26 2014
On Sunday, 27 July 2014 at 06:06:03 UTC, Ola Fosheim Grøstad wrote:On Friday, 25 July 2014 at 17:32:38 UTC, Andrei Alexandrescu wrote:Sure, it could be used as a lightweight bugtracker. But them, someone would have to watch the comments, and actually turn them into PRs, and remove the comments when the PRs are merged.Why? I don't have much context but a few people I talked to were positive about the community contribution to php docs. -- AndreiI find the php comments useful when I have to use the docs. It isn't about correctness, it is about gotchas and potential work-arounds. No worse than stack overflow. There is noise, but it makes no difference at the bottom of the page. People are also more likely to comment there than submitting a formal complaint about errors in the docs.
Jul 27 2014
On Sunday, 27 July 2014 at 08:23:05 UTC, Marc Schütz wrote:Sure, it could be used as a lightweight bugtracker. But them, someone would have to watch the comments, and actually turn them into PRs, and remove the comments when the PRs are merged.I also find example code useful sometimes when a function/feature is under-documented or just plain buggy. If people added the examples they provide in the forums to the doc pages then it would be easier to learn the language? If people added links to stackoverflow/articles when they find them, and put it in the correct section, then it would be easier to dig deeper into the knowledge base? You could have a "sign of authority" on usernames that are official "D experts" and let them "approve" correct comments. When you have received N approvals you can win a D T-shirt? :) A lot of noise is a sign of a documentation page that needs work or that the page need to be broken up into several pages.
Jul 27 2014