Re: How to append range to array?

2015-05-25 Thread John Colvin via Digitalmars-d-learn
On Saturday, 23 May 2015 at 07:03:35 UTC, Vladimir Panteleev 
wrote:

int[] arr = [1, 2, 3];
auto r = iota(4, 10);
// ???
assert(equal(arr, iota(1, 10)));

Hopefully in one GC allocation (assuming we know the range's 
length).


I tried std.range.primitives.put but its behavior seems a 
little mysterious:


This compiles but asserts at runtime:

int[] arr = [1, 2, 3];
arr.put(iota(4, 10));

And this is even weirder, can you guess what it will print?

int[] arr = [1, 2, 3];
arr.put(4);
writeln(arr);


int[] arr = [1,2,3];
auto r = iota(4, 10);
auto app = arr.refAppender;
app.put(r);
assert(equal(arr, iota(1, 10)));

which of course you wrap with something like

auto append(T, R)(ref T arr, R r)
if(is(T : Q[], Q)  isInputRange!r);
{
auto app = arr.refAppender;
app.put(r);
return arr;
}

to get

int[] arr = [1,2,3];
auto r = iota(4, 10);
arr.append(r);
assert(equal(arr, iota(1, 10)));

Walter has mentioned that he was interested in adding more 
range-awareness to the language, so who knows, maybe this sort of 
thing will get sugar at some point.


Re: How to append range to array?

2015-05-24 Thread Steven Schveighoffer via Digitalmars-d-learn

On 5/23/15 4:27 AM, Jonathan M Davis via Digitalmars-d-learn wrote:

On Saturday, May 23, 2015 07:03:33 Vladimir Panteleev via Digitalmars-d-learn 
wrote:

int[] arr = [1, 2, 3];
auto r = iota(4, 10);
// ???
assert(equal(arr, iota(1, 10)));

Hopefully in one GC allocation (assuming we know the range's
length).

I tried std.range.primitives.put but its behavior seems a little
mysterious:

This compiles but asserts at runtime:

int[] arr = [1, 2, 3];
arr.put(iota(4, 10));

And this is even weirder, can you guess what it will print?

int[] arr = [1, 2, 3];
arr.put(4);
writeln(arr);


For better or worse, put does not append to arrays. It fills them. If you
want to append using put, then using std.array.Appender.


Yes, think of an array as a buffer. When you put into it, you are 
overwriting the contents.


In addition to using Appender (which BTW will add an allocation), you 
can extend the array and then fill the extended slice:


auto oldlen = arr.length;
arr.length += someRange.length;
put(arr[oldlen..$], someRange);

I wish there was a shorter way to do this...

-Steve


Re: How to append range to array?

2015-05-24 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, May 24, 2015 22:13:25 Steven Schveighoffer via Digitalmars-d-learn 
wrote:
 On 5/23/15 4:27 AM, Jonathan M Davis via Digitalmars-d-learn wrote:
  On Saturday, May 23, 2015 07:03:33 Vladimir Panteleev via 
  Digitalmars-d-learn wrote:
  int[] arr = [1, 2, 3];
  auto r = iota(4, 10);
  // ???
  assert(equal(arr, iota(1, 10)));
 
  Hopefully in one GC allocation (assuming we know the range's
  length).
 
  I tried std.range.primitives.put but its behavior seems a little
  mysterious:
 
  This compiles but asserts at runtime:
 
  int[] arr = [1, 2, 3];
  arr.put(iota(4, 10));
 
  And this is even weirder, can you guess what it will print?
 
  int[] arr = [1, 2, 3];
  arr.put(4);
  writeln(arr);
 
  For better or worse, put does not append to arrays. It fills them. If you
  want to append using put, then using std.array.Appender.

 Yes, think of an array as a buffer. When you put into it, you are
 overwriting the contents.

 In addition to using Appender (which BTW will add an allocation), you
 can extend the array and then fill the extended slice:

 auto oldlen = arr.length;
 arr.length += someRange.length;
 put(arr[oldlen..$], someRange);

 I wish there was a shorter way to do this...

Honestly, I think that output ranges need at least a minor redesign. They
haven't been used as heavily as input ranges and really aren't ironed out as
well. A prime example of this is that output ranges assume that put will
succeed, and there's no way to even ask how much room an output range has
left or whether a call to put will succeed or not. The current state of
things works reasonably well with Appender, but it's abysmal if you're
dealing with arrays.

- Jonathan M Davis



How to append range to array?

2015-05-23 Thread Vladimir Panteleev via Digitalmars-d-learn

int[] arr = [1, 2, 3];
auto r = iota(4, 10);
// ???
assert(equal(arr, iota(1, 10)));

Hopefully in one GC allocation (assuming we know the range's 
length).


I tried std.range.primitives.put but its behavior seems a little 
mysterious:


This compiles but asserts at runtime:

int[] arr = [1, 2, 3];
arr.put(iota(4, 10));

And this is even weirder, can you guess what it will print?

int[] arr = [1, 2, 3];
arr.put(4);
writeln(arr);


Re: How to append range to array?

2015-05-23 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, May 23, 2015 07:03:33 Vladimir Panteleev via Digitalmars-d-learn 
wrote:
 int[] arr = [1, 2, 3];
 auto r = iota(4, 10);
 // ???
 assert(equal(arr, iota(1, 10)));

 Hopefully in one GC allocation (assuming we know the range's
 length).

 I tried std.range.primitives.put but its behavior seems a little
 mysterious:

 This compiles but asserts at runtime:

 int[] arr = [1, 2, 3];
 arr.put(iota(4, 10));

 And this is even weirder, can you guess what it will print?

 int[] arr = [1, 2, 3];
 arr.put(4);
 writeln(arr);

For better or worse, put does not append to arrays. It fills them. If you
want to append using put, then using std.array.Appender.

- Jonathan M Davis



Re: How to append range to array?

2015-05-23 Thread Atila Neves via Digitalmars-d-learn

std.range.chain?

Atila

On Saturday, 23 May 2015 at 07:03:35 UTC, Vladimir Panteleev 
wrote:

int[] arr = [1, 2, 3];
auto r = iota(4, 10);
// ???
assert(equal(arr, iota(1, 10)));

Hopefully in one GC allocation (assuming we know the range's 
length).


I tried std.range.primitives.put but its behavior seems a 
little mysterious:


This compiles but asserts at runtime:

int[] arr = [1, 2, 3];
arr.put(iota(4, 10));

And this is even weirder, can you guess what it will print?

int[] arr = [1, 2, 3];
arr.put(4);
writeln(arr);




Re: How to append range to array?

2015-05-23 Thread weaselcat via Digitalmars-d-learn
On Saturday, 23 May 2015 at 07:03:35 UTC, Vladimir Panteleev 
wrote:

int[] arr = [1, 2, 3];
auto r = iota(4, 10);
// ???
assert(equal(arr, iota(1, 10)));


import std.array : array;
arr ~ r.array;


Re: How to append range to array?

2015-05-23 Thread weaselcat via Digitalmars-d-learn

On Saturday, 23 May 2015 at 08:35:45 UTC, weaselcat wrote:
On Saturday, 23 May 2015 at 07:03:35 UTC, Vladimir Panteleev 
wrote:

int[] arr = [1, 2, 3];
auto r = iota(4, 10);
// ???
assert(equal(arr, iota(1, 10)));


import std.array : array;
arr ~ r.array;


woops, meant ~=

but this is probably fairly inefficient. Working with ranges and
arrays at the same time feels really badly designed.


Re: How to append range to array?

2015-05-23 Thread Jonathan M Davis via Digitalmars-d-learn
On Saturday, May 23, 2015 08:36:47 weaselcat via Digitalmars-d-learn wrote:
 On Saturday, 23 May 2015 at 08:35:45 UTC, weaselcat wrote:
  On Saturday, 23 May 2015 at 07:03:35 UTC, Vladimir Panteleev
  wrote:
  int[] arr = [1, 2, 3];
  auto r = iota(4, 10);
  // ???
  assert(equal(arr, iota(1, 10)));
 
  import std.array : array;
  arr ~ r.array;

 woops, meant ~=

 but this is probably fairly inefficient. Working with ranges and
 arrays at the same time feels really badly designed.

It's fine if you're not interchanging them. It sounds like he probably wants
to append to an existing array after some set of range operations are done.
And that's not really any different from converting a range to an array via
std.array.array except that the result ends up on the end of an existing
array. The problem is that the output range API doesn't support that,
because it treats arrays as buffers to be filled rather than appending to
them. So, you probably either end up having to use Appender instead of a
naked array, or you have to use foreach and append manually (or you could
use std.array.array. and append the result, but I'd be surprised if that
weren't less efficient).

The problem is when you're trying to do range-based operations and throw
array-specific operations in the middle of it. _That_ is what needs to be
avoided.

- Jonathan M Davis