[Article Contest, first draft] D Slices

Steven Schveighoffer schveiguy at yahoo.com
Wed May 18 13:48:25 PDT 2011


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


More information about the Digitalmars-d mailing list