Re: Why are static arrays not ranges?

2015-09-21 Thread jmh530 via Digitalmars-d-learn

On Monday, 21 September 2015 at 20:33:10 UTC, Jack Stouffer wrote:


That's ridiculous. Do I have to wrap my static arrays in 
structs to get range primitives?


Is there an actual reason for this?


I had done basically the same thing. Below is my naive 
implementation.


import std.traits;
import std.range;
import std.array : array;
import std.stdio : writeln;
import std.algorithm : map;

struct hybrid_array(T : U[N], U, size_t N)
if ( isStaticArray!T )
{
T static_array;
private auto _length = static_array.length;
auto domain = iota(0, static_array.length);

this(T x)
{
static_array = x;
}

@property bool empty()
{
return domain.empty;
}

@property size_t length()
{
return _length;
}

@property U front()
{
assert(!empty);
return static_array[domain.front];
}

void popFront()
{
assert(!empty);
domain.popFront;
_length--;
}

@property hybrid_array save()
{
return this;
}

@property U back()
{
assert(!empty);
return static_array[domain.back];
}

void popBack()
{
assert(!empty);
domain.popBack;
_length++;
}

U opIndex(size_t val)
{
assert(!empty);
return static_array[domain[val]];
}
}

void main()
{
int[5] x = [0, 10, 2, 6, 1];
//auto squares = map!(a => a * a)(x); //doesn't work

auto range = iota(0, x.length).array;

alias h_array = hybrid_array!(int[5]);
auto y = h_array(x);

writeln( isRandomAccessRange!(typeof(y)) );

auto squares = map!(a => a * a)(y); //success, does work
writeln(squares);
}


Re: Why are static arrays not ranges?

2015-09-21 Thread Jonathan M Davis via Digitalmars-d-learn
On Monday, September 21, 2015 20:46:51 Jack Stouffer via Digitalmars-d-learn 
wrote:
> On Monday, 21 September 2015 at 20:39:55 UTC, Jesse Phillips
> wrote:
> > A static array has a constant length, so it is not possible to
> > popFront on a static array.
> >
> > Making a dynamic array from it is easy, just slice it with []:
> >
> >  pragma(msg, isInputRange!(typeof(a[])));
> >  pragma(msg, isForwardRange!(typeof(a[])));
> >  pragma(msg, isRandomAccessRange!(typeof(a[])));
>
> Thanks for all of the replies. I was under the impression that
> the slicer allocated GC, but some tests show that's not true.

All that slicing a static array does is give you a dynamic array which
refers to the static array. It's then the same as any other dynamic array
except that you have to make sure that it doesn't continue to refer to the
static array after the static array no longer exists, and it's guaranteed to
have no extra capacity, so if you do append to it, it's guaranteed to
reallocate, whereas one allocated via new may or may not have extra
capacity, depending on what's been done with that dynamic array and any
other dynamic arrays were sliced from it and thus may or may not have to be
reallocated when it's appended to. Similarly, slicing malloced memory gets
you a dynamic array which refers to malloced memory and thus has no extra
capacity, and you have to be careful to not still have it around when the
malloced memory is freed.

I would suggest that you read this

http://dlang.org/d-array-article.html

and possibly watch this

http://dconf.org/2015/talks/davis.html

- Jonathan M Davis



Re: Why are static arrays not ranges?

2015-09-21 Thread cym13 via Digitalmars-d-learn

On Monday, 21 September 2015 at 20:33:10 UTC, Jack Stouffer wrote:

import std.range;

void main() {
int[6] a = [1, 2, 3, 4, 5, 6];

pragma(msg, isInputRange!(typeof(a)));
pragma(msg, isForwardRange!(typeof(a)));
pragma(msg, isRandomAccessRange!(typeof(a)));
}

$ dmd -run test.d
false
false
false

That's ridiculous. Do I have to wrap my static arrays in 
structs to get range primitives?


Is there an actual reason for this?


For an element of explanation see my answer at a similar question 
here:


http://forum.dlang.org/post/xdhuberedpjuxydbw...@forum.dlang.org


Re: Why are static arrays not ranges?

2015-09-21 Thread Jesse Phillips via Digitalmars-d-learn

On Monday, 21 September 2015 at 20:33:10 UTC, Jack Stouffer wrote:

import std.range;

void main() {
int[6] a = [1, 2, 3, 4, 5, 6];

pragma(msg, isInputRange!(typeof(a)));
pragma(msg, isForwardRange!(typeof(a)));
pragma(msg, isRandomAccessRange!(typeof(a)));
}

$ dmd -run test.d
false
false
false

That's ridiculous. Do I have to wrap my static arrays in 
structs to get range primitives?


Is there an actual reason for this?


A static array has a constant length, so it is not possible to 
popFront on a static array.


Making a dynamic array from it is easy, just slice it with []:

 pragma(msg, isInputRange!(typeof(a[])));
 pragma(msg, isForwardRange!(typeof(a[])));
 pragma(msg, isRandomAccessRange!(typeof(a[])));


Re: Why are static arrays not ranges?

2015-09-21 Thread Adam D. Ruppe via Digitalmars-d-learn

On Monday, 21 September 2015 at 20:33:10 UTC, Jack Stouffer wrote:

pragma(msg, isInputRange!(typeof(a)));


try:

 pragma(msg, isInputRange!(typeof(a[])));

Notice the addition of the [] after the a. That's the slicing 
operator and it will yield a range.



Is there an actual reason for this?


A static array is a container; a block of memory. A range is a 
*view* into a container. When you popFront a range, you aren't 
modifying the underlying memory, you are just advancing the view 
to the next element. popFront of a static array is impossible 
anyway due to the immutability of its length, but even if it was 
possible, advancing your view to the next item should not 
actually delete the item if at all possible.


Dynamic arrays are actually similar btw, the underlying container 
for them is just hidden from view because the garbage collector 
manages it, so all you see is the slice (view/range).


Re: Why are static arrays not ranges?

2015-09-21 Thread anonymous via Digitalmars-d-learn
On Monday 21 September 2015 22:33, Jack Stouffer wrote:

> import std.range;
> 
> void main() {
>  int[6] a = [1, 2, 3, 4, 5, 6];
> 
>  pragma(msg, isInputRange!(typeof(a)));
>  pragma(msg, isForwardRange!(typeof(a)));
>  pragma(msg, isRandomAccessRange!(typeof(a)));
> }
> 
> $ dmd -run test.d
> false
> false
> false
> 
> That's ridiculous. Do I have to wrap my static arrays in structs 
> to get range primitives?

You can just slice them: `a[]` is an `int[]` which is a range.

> Is there an actual reason for this?

How would popFront work on an `int[6]`? popFront can't change the type, but 
it must remove an element.


Re: Why are static arrays not ranges?

2015-09-21 Thread Jack Stouffer via Digitalmars-d-learn
On Monday, 21 September 2015 at 20:39:55 UTC, Jesse Phillips 
wrote:
A static array has a constant length, so it is not possible to 
popFront on a static array.


Making a dynamic array from it is easy, just slice it with []:

 pragma(msg, isInputRange!(typeof(a[])));
 pragma(msg, isForwardRange!(typeof(a[])));
 pragma(msg, isRandomAccessRange!(typeof(a[])));


Thanks for all of the replies. I was under the impression that 
the slicer allocated GC, but some tests show that's not true.