www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - [Article Contest, first draft] D Slices

reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
next sibling parent David Gileadi <gileadis NSPMgmail.com> writes:
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
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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:
 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.

Thanks!
 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
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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.

May 18 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
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
prev sibling next sibling parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
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
parent reply Jesse Phillips <jessekphillips+D gmail.com> writes:
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 ;)
 
 -Steve

Go 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
parent Jesse Phillips <jessekphillips+D gmail.com> writes:
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 Davis

I 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
prev sibling next sibling parent "Alex_Dovhal" <alex_dovhal yahoo.com> writes:
"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

 -Steve

Nice 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"

   fillAs(str, 12);     // buffer can be extended in place!
   writeln(str);        // "AAAAAAAAAA";
}

Please add in (1) assert(str.capacity == 15);
May 18 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Wed, 18 May 2011 16:37:49 -0400, Jesse Phillips  
<jessekphillips+D gmail.com> wrote:

 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.

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 ;) -Steve
May 18 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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:

 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"

   fillAs(str, 12);     // buffer can be extended in place!
   writeln(str);        // "AAAAAAAAAA";
 }

Please add in (1) assert(str.capacity == 15);

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! -Steve
May 18 2011
prev sibling next sibling parent Johann MacDonagh <johann.macdonagh..no spam..gmail.com> writes:
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

 -Steve

Fantastic! 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
prev sibling next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
Asserts are kind of like going to court and interpreting the silence
of the jury as a not guilty verdict. :p
May 18 2011
prev sibling next sibling parent "Jonathan M Davis" <jmdavisProg gmx.com> writes:
 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 ;)
 
 -Steve

Go 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.

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 Davis
May 18 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
On 2011-05-18 21:09, Jesse Phillips wrote:
 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 Davis

I 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

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 Davis
May 18 2011
prev sibling next sibling parent "Lars T. Kyllingstad" <public kyllingen.NOSPAMnet> writes:
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/ArrayArticle

This 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
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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:

 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

This 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.

Thanks!
 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
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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:
 Jonathan M Davis Wrote:
 The huge advantage of assert over writeln is that it shows you what  

 result is supposed to be. If you're reading the code or documentation,
 that's extremely valuable, whereas writeln is useless.



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.
 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  

 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  

 as you read, but writeln when running code because when you do, you  

 see the result.

 - Jonathan M Davis

I 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

Yes. Such assertions should always be passing.

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. -Steve
May 19 2011
prev sibling next sibling parent reply Jens Mueller <jens.k.mueller gmx.de> writes:
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

Any chance to move the article under Articles on d-programming-language.org? More people will find/read it. Jens
May 20 2011
parent Andrei Alexandrescu <SeeWebsiteForEmail erdani.org> writes:
On 5/20/11 12:55 PM, Jens Mueller wrote:
 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

Any chance to move the article under Articles on d-programming-language.org? More people will find/read it. Jens

I'd be glad to. Could someone please put together a pull request? Andrei
May 20 2011
prev sibling next sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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:
 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

Any chance to move the article under Articles on d-programming-language.org? More people will find/read it. Jens

I'd be glad to. Could someone please put together a pull request?

I can do this. -Steve
May 22 2011
prev sibling next sibling parent Jonathan M Davis <jmdavisProg gmx.com> writes:
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/ArrayArticle

Finally 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
prev sibling parent "Steven Schveighoffer" <schveiguy yahoo.com> writes:
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:
 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

Finally 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 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"
 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