On Wed, 18 May 2011 16:22:50 -0400, Andrej Mitrovic <andrej.mitrov...@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

Reply via email to