digitalmars.D - [Article Contest, first draft] D Slices
- Steven Schveighoffer (11/11) May 18 2011 Having seen quite a few incorrect descriptions of how D slices work
- David Gileadi (26/27) May 18 2011 First off, this is a fantastic article. Thanks for clearly explaining a...
- Steven Schveighoffer (6/32) May 18 2011 Thanks!
- Andrej Mitrovic (2/3) May 18 2011 The first sentence! :]
- Steven Schveighoffer (4/5) May 18 2011 Fixed
- Andrej Mitrovic (29/29) May 18 2011 Well consider me enlightened. From all the things I've read before
- Steven Schveighoffer (23/50) May 18 2011 D1 actually had almost this notion -- any slice that started at the
- Jesse Phillips (9/12) May 18 2011 Still reading, but the example should use assertions which pass:
- Steven Schveighoffer (12/25) May 18 2011 I always wonder about that. One of the issues with assert for people
- Andrej Mitrovic (2/2) May 18 2011 Asserts are kind of like going to court and interpreting the silence
- Jesse Phillips (2/16) May 18 2011 Go with writeln, I understand that concern. The counter point I have is ...
- Jonathan M Davis (9/28) May 18 2011 The huge advantage of assert over writeln is that it shows you what the ...
- Jesse Phillips (4/14) May 18 2011 I agree, but he is conflicted on whether the assert should pass or fail....
- Jonathan M Davis (11/31) May 18 2011 Yes. Such assertions should always be passing. If he has a good reason f...
- Steven Schveighoffer (21/50) May 19 2011 Both assert and writeln with a comment describing what is output are
- Alex_Dovhal (6/34) May 18 2011 Nice article, very pleasured to read. One thing that strained my mind - ...
- Steven Schveighoffer (6/30) May 18 2011 hm... I think I'll add a comment instead, since I haven't discussed the ...
- Johann MacDonagh (7/18) May 18 2011 Fantastic! Just a grammar nitpick.
- Lars T. Kyllingstad (8/20) May 19 2011 This is an excellent article! It answers many questions about the new
- Steven Schveighoffer (22/41) May 19 2011 Thanks!
- Jens Mueller (4/18) May 20 2011 Any chance to move the article under Articles on
- Andrei Alexandrescu (3/21) May 20 2011 I'd be glad to. Could someone please put together a pull request?
- Steven Schveighoffer (4/26) May 22 2011 I can do this.
- Jonathan M Davis (14/26) May 22 2011 Finally got around to reading it. Definitely a good article. I even lear...
- Steven Schveighoffer (12/47) May 23 2011 A slice is kind of an opaque type. You shouldn't rely on the exact
Having seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do. Being one of the only places where I have web space, it's on my dcollections site, I probably will move it to the D wiki eventually, but I'm much more familiar with the Trac wiki syntax. Please, if you have any comments or recommendations, let me know. I certainly am no author, so I probably screwed a few things up :) http://www.dsource.org/projects/dcollections/wiki/ArrayArticle Thanks -Steve
May 18 2011
On 5/18/11 11:03 AM, Steven Schveighoffer wrote:Please, if you have any comments or recommendations, let me know.First off, this is a fantastic article. Thanks for clearly explaining a fairly subtle concept. I'm especially happy to finally understand how appending to a slice can avoid reallocating and what assumeSafeAppend does. I do have a couple of nits: 1. After the shrinkTo2 example, you say "This might look like you changed the passed arr's length to 2, but it actually did not affect anything," followed by the reason. It took me a bit to realize why this was so. I think it would be clearer if the example included the call to shrinkTo2, e.g. void shrinkTo2(int[] arr) { if(arr.length > 2) arr.length = 2; } int[] a = new int[5]; shrinkTo2(a); And then you pointed out that a's length hasn't changed after the call. Including the calling code might also be helpful for the Determinism example, for the same reason. 2. In the section "A Slice You Can Append On" the phrase "The slice does not own it's data" should remove the apostrophe from "its". There is at least one other place in the document that also make this mistake, under the Caching section. Again, fantastic article. -Dave
May 18 2011
On Wed, 18 May 2011 14:44:33 -0400, David Gileadi <gileadis nspmgmail.com> wrote:On 5/18/11 11:03 AM, Steven Schveighoffer wrote:Thanks!Please, if you have any comments or recommendations, let me know.First off, this is a fantastic article. Thanks for clearly explaining a fairly subtle concept. I'm especially happy to finally understand how appending to a slice can avoid reallocating and what assumeSafeAppend does.I do have a couple of nits: 1. After the shrinkTo2 example, you say "This might look like you changed the passed arr's length to 2, but it actually did not affect anything," followed by the reason. It took me a bit to realize why this was so. I think it would be clearer if the example included the call to shrinkTo2, e.g. void shrinkTo2(int[] arr) { if(arr.length > 2) arr.length = 2; } int[] a = new int[5]; shrinkTo2(a); And then you pointed out that a's length hasn't changed after the call. Including the calling code might also be helpful for the Determinism example, for the same reason.OK, thanks, I'll do that.2. In the section "A Slice You Can Append On" the phrase "The slice does not own it's data" should remove the apostrophe from "its". There is at least one other place in the document that also make this mistake, under the Caching section.Yes, its a problem I have ;) -Steve
May 18 2011
On 5/18/11, David Gileadi <gileadis nspmgmail.com> wrote:There is at least one other place in the document that also make this mistake.The first sentence! :]
May 18 2011
On Wed, 18 May 2011 14:44:33 -0400, David Gileadi <gileadis nspmgmail.com> wrote:I do have a couple of nits:Fixed -Steve
May 18 2011
Well consider me enlightened. From all the things I've read before this article, I thought a slice is a special feature that is only introduced when you take an [n..m] from an array, e.g. my understanding was something like: int[] a = new int[5]; // a is definitely a dynamic array auto b = a[1..3]; // take a slice and make b an array of length 2, pointing at a[1..3]; Where "making an array" would just mean creating a new struct with a pointer and a length, not allocating memory for the elements. Your article should have been in TDPL. Good work! It might be a good idea to mention how you can take a slice of a static array to make it passable to functions which expect slices. A lot of functions (all of them?) in Phobos expect slices and not static arrays, but it's not at all obvious. E.g. if you try to do this it will fail to compile with an extremely ugly message: int[4] arr1 = [ 1, 2, 3, 4 ]; auto mapped = map!("a + a")(arr1); testmap.d(10): Error: template std.algorithm.map!("a + a").map(Range) if (isInputRange!(Unqual!(Range))) does not match any function template declaration testmap.d(10): Error: template std.algorithm.map!("a + a").map(Range) if (isInputRange!(Unqual!(Range))) cannot deduce template function from argument types !()(int[4u]) All that has to be done is to take a slice: int[4] arr1 = [ 1, 2, 3, 4 ]; auto mapped = map!("a + a")(arr1[]); Come to think of it, these types of errors could be caught by the compiler to output a nicer error message, imo.
May 18 2011
On Wed, 18 May 2011 16:22:50 -0400, Andrej Mitrovic <andrej.mitrovich gmail.com> wrote:Well consider me enlightened. From all the things I've read before this article, I thought a slice is a special feature that is only introduced when you take an [n..m] from an array, e.g. my understanding was something like: int[] a = new int[5]; // a is definitely a dynamic array auto b = a[1..3]; // take a slice and make b an array of length 2, pointing at a[1..3]; Where "making an array" would just mean creating a new struct with a pointer and a length, not allocating memory for the elements.D1 actually had almost this notion -- any slice that started at the beginning of a block was considered the "owner" slice. The only issue was, you could have several slices think they own the data, which leads to bad things if you append to more than one of them. This is where the "stomping" issue came in. We all just dealt with it.Your article should have been in TDPL. Good work!Thanks!It might be a good idea to mention how you can take a slice of a static array to make it passable to functions which expect slices. A lot of functions (all of them?) in Phobos expect slices and not static arrays, but it's not at all obvious.This is a good idea, I should probably add to the section that demonstrates slices to show how slicing can be used on things other than heap-allocated arrays (although I allude to that in one part).E.g. if you try to do this it will fail to compile with an extremely ugly message: int[4] arr1 = [ 1, 2, 3, 4 ]; auto mapped = map!("a + a")(arr1); testmap.d(10): Error: template std.algorithm.map!("a + a").map(Range) if (isInputRange!(Unqual!(Range))) does not match any function template declaration testmap.d(10): Error: template std.algorithm.map!("a + a").map(Range) if (isInputRange!(Unqual!(Range))) cannot deduce template function from argument types !()(int[4u]) All that has to be done is to take a slice: int[4] arr1 = [ 1, 2, 3, 4 ]; auto mapped = map!("a + a")(arr1[]);This is really more of a problem with map and IFTI than arrays. The error message is actually accurate (a fixed-sized array is not a range). What would be nice is to say, "if map is called with a static array, slice it first". I think you would probably need some sort of wrapper call: auto map(alias pred, T)(ref T t) if(isStaticArray!T) { return map!(pred)(t[]); } But you'd have to do this for every template function that takes a range. I don't know of a better way the compiler could do it, IFTI is very simple when it comes to interpreting what argument type it should use. -Steve
May 18 2011
Steven Schveighoffer Wrote:Having seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do.Still reading, but the example should use assertions which pass: void main() { int[] arr = new int[5]; shrinkTo2(arr); assert(arr.length != 2); // Not expected! } It is good form because reading it will describe the outcome even without comment.
May 18 2011
On Wed, 18 May 2011 16:37:49 -0400, Jesse Phillips <jessekphillips+D gmail.com> wrote:Steven Schveighoffer Wrote:I always wonder about that. One of the issues with assert for people "feeling" out the language is, a passing assert doesn't seem to do anything. For instance, in this example, if you take the code I wrote, and compile it, you'll get a loud assertion error (proving the assertion runs and fails). If you take your code and run it, you get a command prompt. It doesn't really help you see how it works. I'm contemplating switching it to a writeln instead ;) -SteveHaving seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do.Still reading, but the example should use assertions which pass: void main() { int[] arr = new int[5]; shrinkTo2(arr); assert(arr.length != 2); // Not expected! } It is good form because reading it will describe the outcome even without comment.
May 18 2011
Asserts are kind of like going to court and interpreting the silence of the jury as a not guilty verdict. :p
May 18 2011
Steven Schveighoffer Wrote:I always wonder about that. One of the issues with assert for people "feeling" out the language is, a passing assert doesn't seem to do anything. For instance, in this example, if you take the code I wrote, and compile it, you'll get a loud assertion error (proving the assertion runs and fails). If you take your code and run it, you get a command prompt. It doesn't really help you see how it works. I'm contemplating switching it to a writeln instead ;) -SteveGo with writeln, I understand that concern. The counter point I have is that this is how unittests work and much of the documentation has been written.
May 18 2011
Steven Schveighoffer Wrote:The huge advantage of assert over writeln is that it shows you what the result is supposed to be. If you're reading the code or documentation, that's extremely valuable, whereas writeln is useless. However, if what you're concerned about is running the code and see the result, writeln is far more useful. Since you're writing an article, I would definitely go with assert, but it really depends on what you're trying to do. assert works far better as documentation because you can see the result as you read, but writeln when running code because when you do, you can see the result. - Jonathan M DavisI always wonder about that. One of the issues with assert for people "feeling" out the language is, a passing assert doesn't seem to do anything. For instance, in this example, if you take the code I wrote, and compile it, you'll get a loud assertion error (proving the assertion runs and fails). If you take your code and run it, you get a command prompt. It doesn't really help you see how it works. I'm contemplating switching it to a writeln instead ;) -SteveGo with writeln, I understand that concern. The counter point I have is that this is how unittests work and much of the documentation has been written.
May 18 2011
Jonathan M Davis Wrote:The huge advantage of assert over writeln is that it shows you what the result is supposed to be. If you're reading the code or documentation, that's extremely valuable, whereas writeln is useless. However, if what you're concerned about is running the code and see the result, writeln is far more useful. Since you're writing an article, I would definitely go with assert, but it really depends on what you're trying to do. assert works far better as documentation because you can see the result as you read, but writeln when running code because when you do, you can see the result. - Jonathan M DavisI agree, but he is conflicted on whether the assert should pass or fail. By your logic though it sound like you want it also passing. There isn't much difference between these: assert(arr.length == 2); // error! wirteln(arr.length); // 5
May 18 2011
On 2011-05-18 21:09, Jesse Phillips wrote:Jonathan M Davis Wrote:Yes. Such assertions should always be passing. If he has a good reason for not just doing assert(arr.length != 2); then what the best choice is depends on what he's really doing. I haven't gotten the chance to read the article yet though, so I don't know exactly what he's trying to do. In the general case, however, I think that for documentation and articles, the best choice is to use assertions which pass - particularly those which use == - because then it's clear what's actually happening without having to run the code. - Jonathan M DavisThe huge advantage of assert over writeln is that it shows you what the result is supposed to be. If you're reading the code or documentation, that's extremely valuable, whereas writeln is useless. However, if what you're concerned about is running the code and see the result, writeln is far more useful. Since you're writing an article, I would definitely go with assert, but it really depends on what you're trying to do. assert works far better as documentation because you can see the result as you read, but writeln when running code because when you do, you can see the result. - Jonathan M DavisI agree, but he is conflicted on whether the assert should pass or fail. By your logic though it sound like you want it also passing. There isn't much difference between these: assert(arr.length == 2); // error! wirteln(arr.length); // 5
May 18 2011
On Thu, 19 May 2011 00:27:51 -0400, Jonathan M Davis <jmdavisProg gmx.com> wrote:On 2011-05-18 21:09, Jesse Phillips wrote:Both assert and writeln with a comment describing what is output are equally as useful for code that is not compiled and executed (i.e. you are just reading). Both describe what you should expect, and you can't really prove it is wrong without compiling and executing. writeln is just a little more friendly to those who want to see something happening when you do actually execute it. Whenever I'm learning a language, I like to write little test programs to print out what's going on to make sure I understand it.Jonathan M Davis Wrote:The huge advantage of assert over writeln is that it shows you whattheresult is supposed to be. If you're reading the code or documentation, that's extremely valuable, whereas writeln is useless.Shouldn't asserts be what you *expect* the value to be? For example, in this case, a novice programmer may have written this code expecting that the value should be 2. At least, that's what I was going for when I wrote an assert that I knew would throw an error. I agree that proper documentation for the D spec or library modules should specify all passing asserts. Especially when eventually these examples are used as unit tests. In any case, I'm going to change it to writeln. Thanks for all the opinions on this, it definitely helps to see what other people are thinking. -SteveYes. Such assertions should always be passing.However, if what you're concerned about is running the code and see the result, writeln is far more useful. Since you're writing an article, I woulddefinitelygo with assert, but it really depends on what you're trying to do. assert works far better as documentation because you can see theresultas you read, but writeln when running code because when you do, youcansee the result. - Jonathan M DavisI agree, but he is conflicted on whether the assert should pass or fail. By your logic though it sound like you want it also passing. There isn't much difference between these: assert(arr.length == 2); // error! wirteln(arr.length); // 5
May 19 2011
"Steven Schveighoffer" <schveiguy yahoo.com> сообщил/сообщила в новостях следующее: news:op.vvou3fbgeav7ka localhost.localdomain...Having seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do. Being one of the only places where I have web space, it's on my dcollections site, I probably will move it to the D wiki eventually, but I'm much more familiar with the Trac wiki syntax. Please, if you have any comments or recommendations, let me know. I certainly am no author, so I probably screwed a few things up :) http://www.dsource.org/projects/dcollections/wiki/ArrayArticle Thanks -SteveNice article, very pleasured to read. One thing that strained my mind - this exaple:import std.stdio; char[] fillAs(char[] buf, size_t num) { if(buf.length < num) buf.length = num; // increase buffer length to be able to hold the A's buf[0..num] = 'A'; // assign A to all the elements return buf[0..num]; // return the result } void main() { char[] str = new char[10]; str[] = 'B'; fillAs(str, 20); // buffer must be reallocated writeln(str); // "BBBBBBBBBB"(1)fillAs(str, 12); // buffer can be extended in place! writeln(str); // "AAAAAAAAAA"; }Please add in (1) assert(str.capacity == 15);
May 18 2011
On Wed, 18 May 2011 16:47:47 -0400, Alex_Dovhal <alex_dovhal yahoo.com> wrote:Nice article, very pleasured to read. One thing that strained my mind - this exaple:hm... I think I'll add a comment instead, since I haven't discussed the capacity property yet. People might not get what that means. Thanks for the suggestion! -Steveimport std.stdio; char[] fillAs(char[] buf, size_t num) { if(buf.length < num) buf.length = num; // increase buffer length to be able to hold the A's buf[0..num] = 'A'; // assign A to all the elements return buf[0..num]; // return the result } void main() { char[] str = new char[10]; str[] = 'B'; fillAs(str, 20); // buffer must be reallocated writeln(str); // "BBBBBBBBBB"(1)fillAs(str, 12); // buffer can be extended in place! writeln(str); // "AAAAAAAAAA"; }Please add in (1) assert(str.capacity == 15);
May 18 2011
On 5/18/2011 2:03 PM, Steven Schveighoffer wrote:Having seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do. Being one of the only places where I have web space, it's on my dcollections site, I probably will move it to the D wiki eventually, but I'm much more familiar with the Trac wiki syntax. Please, if you have any comments or recommendations, let me know. I certainly am no author, so I probably screwed a few things up :) http://www.dsource.org/projects/dcollections/wiki/ArrayArticle Thanks -SteveFantastic! Just a grammar nitpick. Caching: we employ a caching technique that is as far as I know, unique to D. should be: we employ a caching technique that is, as far as I know, unique to D. This seriously should be in the next TDPL ;)
May 18 2011
On Wed, 18 May 2011 14:03:05 -0400, Steven Schveighoffer wrote:Having seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do. Being one of the only places where I have web space, it's on my dcollections site, I probably will move it to the D wiki eventually, but I'm much more familiar with the Trac wiki syntax. Please, if you have any comments or recommendations, let me know. I certainly am no author, so I probably screwed a few things up :) http://www.dsource.org/projects/dcollections/wiki/ArrayArticleThis is an excellent article! It answers many questions about the new appending system which I've been meaning to ask you for a long time. One question, still: It seems inconsistent that the value of capacity() normally includes the existing slice elements, yet suddenly returns 0 when the array cannot be appended to. Why doesn't it return slice.length? -Lars
May 19 2011
On Thu, 19 May 2011 07:42:57 -0400, Lars T. Kyllingstad <public kyllingen.nospamnet> wrote:On Wed, 18 May 2011 14:03:05 -0400, Steven Schveighoffer wrote:Thanks!Having seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do. Being one of the only places where I have web space, it's on my dcollections site, I probably will move it to the D wiki eventually, but I'm much more familiar with the Trac wiki syntax. Please, if you have any comments or recommendations, let me know. I certainly am no author, so I probably screwed a few things up :) http://www.dsource.org/projects/dcollections/wiki/ArrayArticleThis is an excellent article! It answers many questions about the new appending system which I've been meaning to ask you for a long time.One question, still: It seems inconsistent that the value of capacity() normally includes the existing slice elements, yet suddenly returns 0 when the array cannot be appended to. Why doesn't it return slice.length?Well, I think someone has brought that up before, and I thought it was a good idea, but I found a reason recently for leaving it the way it is. If an array has completely filled a memory block, and you have a slice that ends at the end of that memory block, the capacity will be equal to the slice length. This might be a condition you want to know, vs a slice that does not end at the end of the array (which currently returns capacity of 0). The example I found was a recent request for a way to safely remove an element from a slice. I recommended to use assumeSafeAppend after removing the element. The question was then asked, what if the slice is part of a larger array? Calling assumeSafeAppend effectively invalidates all elements after the slice. So you want to know positively that a slice ends at the end of the array, and only call assumeSafeAppend if it's safe to do so. Maybe there is a better way to do this, but it turns out to be a useful inconsistency. Keep in mind that calling capacity is not a simple quick lookup, so you don't want to have to call it multiple times. Slices of non-heap arrays also return a capacity of 0. -Steve
May 19 2011
Steven Schveighoffer wrote:Having seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do. Being one of the only places where I have web space, it's on my dcollections site, I probably will move it to the D wiki eventually, but I'm much more familiar with the Trac wiki syntax. Please, if you have any comments or recommendations, let me know. I certainly am no author, so I probably screwed a few things up :) http://www.dsource.org/projects/dcollections/wiki/ArrayArticle ThanksAny chance to move the article under Articles on d-programming-language.org? More people will find/read it. Jens
May 20 2011
On 5/20/11 12:55 PM, Jens Mueller wrote:Steven Schveighoffer wrote:I'd be glad to. Could someone please put together a pull request? AndreiHaving seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do. Being one of the only places where I have web space, it's on my dcollections site, I probably will move it to the D wiki eventually, but I'm much more familiar with the Trac wiki syntax. Please, if you have any comments or recommendations, let me know. I certainly am no author, so I probably screwed a few things up :) http://www.dsource.org/projects/dcollections/wiki/ArrayArticle ThanksAny chance to move the article under Articles on d-programming-language.org? More people will find/read it. Jens
May 20 2011
On Fri, 20 May 2011 13:57:15 -0400, Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> wrote:On 5/20/11 12:55 PM, Jens Mueller wrote:I can do this. -SteveSteven Schveighoffer wrote:I'd be glad to. Could someone please put together a pull request?Having seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do. Being one of the only places where I have web space, it's on my dcollections site, I probably will move it to the D wiki eventually, but I'm much more familiar with the Trac wiki syntax. Please, if you have any comments or recommendations, let me know. I certainly am no author, so I probably screwed a few things up :) http://www.dsource.org/projects/dcollections/wiki/ArrayArticle ThanksAny chance to move the article under Articles on d-programming-language.org? More people will find/read it. Jens
May 22 2011
On 2011-05-18 11:03, Steven Schveighoffer wrote:Having seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do. Being one of the only places where I have web space, it's on my dcollections site, I probably will move it to the D wiki eventually, but I'm much more familiar with the Trac wiki syntax. Please, if you have any comments or recommendations, let me know. I certainly am no author, so I probably screwed a few things up :) http://www.dsource.org/projects/dcollections/wiki/ArrayArticleFinally got around to reading it. Definitely a good article. I even learned a few things from it (primarily surrounding implementation details). I am a bit surprised that you never mentioned that a slice is essentially struct with the a C style array pointer and the length of the slice (particularly since that helps to explain why passing an array without ref means that altering the slice rather than its elements doesn't alter the array that was passed in), but it still works quite well without that. A couple of total nitpicks would be that the first sentence should say "...is its implementation..." rather than using "are", and the title "A Slice You Can Append On" should be "A Slice You Can Append To." But as those just nitpicky grammar issues. Overall, it's very good and definitely something that D programmers (especially newbies) should read. Dynamic arrays and slices throw them off too often. - Jonathan M Davis
May 22 2011
On Sun, 22 May 2011 22:46:13 -0400, Jonathan M Davis <jmdavisProg gmx.com> wrote:On 2011-05-18 11:03, Steven Schveighoffer wrote:A slice is kind of an opaque type. You shouldn't rely on the exact implementation (at one point, Walter was considering changing it to a begin and end pointer), although I do describe its implementation, without saying it's a struct: "A slice is a segment of an array (dynamic or otherwise) that tracks both the pointer and the length of the segment"Having seen quite a few incorrect descriptions of how D slices work (particularly regarding appending), I wrote an article that tries to describe how D slices work, and why they behave the way they do. Being one of the only places where I have web space, it's on my dcollections site, I probably will move it to the D wiki eventually, but I'm much more familiar with the Trac wiki syntax. Please, if you have any comments or recommendations, let me know. I certainly am no author, so I probably screwed a few things up :) http://www.dsource.org/projects/dcollections/wiki/ArrayArticleFinally got around to reading it. Definitely a good article. I even learned a few things from it (primarily surrounding implementation details). I am a bit surprised that you never mentioned that a slice is essentially struct with the a C style array pointer and the length of the slice (particularly since that helps to explain why passing an array without ref means that altering the slice rather than its elements doesn't alter the array that was passed in), but it still works quite well without that.A couple of total nitpicks would be that the first sentence should say "...is its implementation..." rather than using "are",Fixed, thanks!and the title "A Slice You Can Append On" should be "A Slice You Can Append To."This was intentional :) It's a pun (something "you can depend on").But as those just nitpicky grammar issues. Overall, it's very good and definitely something that D programmers (especially newbies) should read. Dynamic arrays and slices throw them off too often.Thanks! -Steve
May 23 2011