Re: `clear`ing a dynamic array

2015-10-25 Thread qsdfghjk via Digitalmars-d-learn
On Saturday, 24 October 2015 at 13:18:26 UTC, Shriramana Sharma 
wrote:
Hello. I had first expected that dynamic arrays (slices) would 
provide a `.clear()` method but they don't seem to. Obviously I 
can always effectively clear an array by assigning an empty 
array to it, but this has unwanted consequences that `[]` 
actually seems to allocate a new dynamic array and any other 
identifiers initially pointing to the same array will still 
show the old contents and thus it would no longer test true for 
`is` with this array. See the following code:


import std.stdio;
void main()
{
  int a[] = [1,2,3,4,5];
  int b[] = a;
  writeln(a);
  writeln(b);
  //a.clear();
  a = [];
  writeln(a);
  writeln(b);
}

which outputs:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[1, 2, 3, 4, 5]

How to make it so that after clearing `a`, `b` will also point 
to the same empty array? IOW the desired output is:


[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[]

... and any further items added to `a` should also reflect in 
`b`.


If you don't want to mess with pointers (as sugggested in the 
first answer) you can also use std.typecons.RefCounted:


---
import std.stdio;
import std.typecons;

RefCounted!(int[]) b;

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


Re: `clear`ing a dynamic array

2015-10-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, October 25, 2015 09:34:25 Shriramana Sharma via Digitalmars-d-learn 
wrote:
> rsw0x wrote:
>
> > use std.container.array
>
> Thanks all for all the recommendations. When would one use
> std.array.appender with a built-in array vs std.container.array.Array? What
> are the pros and cons on either side?

Appender is for when you you know that you're going to be doing a whole
bunch of appending to an array, and you'd normally only use it when
initially filling in the array, after which you'd just get the array out of
it and use the array. Appender really isn't intended to be used as a
container - just as a way to make appending more efficient or to have an
output range which is an array but which is appended to by put rather than
just assigning to its existing elements. You don't use Appender to not use
arrays or to get full reference semantics from an array.

If you want a container rather than a dynamic array - especially if you're
looking for full reference semantics - then use std.container.array.Array.

- Jonathan M Davis



Re: `clear`ing a dynamic array

2015-10-25 Thread Olivier Pisano via Digitalmars-d-learn
On Sunday, 25 October 2015 at 04:04:29 UTC, Shriramana Sharma 
wrote:

rsw0x wrote:


use std.container.array


Thanks all for all the recommendations. When would one use 
std.array.appender with a built-in array vs 
std.container.array.Array? What are the pros and cons on either 
side?


Appender is a small wrapper that enables you to get an output 
range from a built-in array. It allocates using the GC. If you 
have an array and you need to pass it to a function that takes an 
output range, you can use it.


std.container.Array is a reference counted container that is 
equivalent to std::shared_ptr in C++. It is not 
reliant on the GC.


Re: `clear`ing a dynamic array

2015-10-25 Thread anonymous via Digitalmars-d-learn
On Sunday, 25 October 2015 at 11:45:53 UTC, Shriramana Sharma 
wrote:
http://dlang.org/arrays.html#resize says: """Also, you may wish 
to utilize the phobos reserve function to pre-allocate array 
data to use with the append operator."""


I presume this means 
http://dlang.org/phobos/std_array.html#.Appender.reserve but 
how `append` is considered an operator is beyond me.


That sentence doesn't refer to std.array.Appender. `reserve` 
means . The append 
operator is `~=`.




Re: `clear`ing a dynamic array

2015-10-25 Thread Shriramana Sharma via Digitalmars-d-learn
Thanks all, for your replies.

Jonathan M Davis via Digitalmars-d-learn wrote:

> If you want a container rather than a dynamic array - especially if you're
> looking for full reference semantics - then use std.container.array.Array.

Hmmm, pardon me but while I'm sure I don't specifically require reference 
semantics, I'm not sure how you mean to contrast a "container" vs a "dynamic 
array". Both are aware of their content count and both are iterable, no? Is 
it that by "container" you mean that something that owns its contents and is 
responsible for deleting them all when it itself is deleted?

-- 
Shriramana Sharma, Penguin #395953


Re: `clear`ing a dynamic array

2015-10-25 Thread Shriramana Sharma via Digitalmars-d-learn
Jonathan M Davis via Digitalmars-d-learn wrote:

> Appender really isn't intended to be used as a
> container - just as a way to make appending more efficient or to have an
> output range which is an array

I get the part about Appender helping to make an output range of a regular 
array, but I'm not sure how it is supposed to make appending "more 
efficient". I just had a look at the std.array code for appender and 
couldn't figure what was so special – obviously it's my limited knowledge. 

http://dlang.org/arrays.html#resize says: """Also, you may wish to utilize 
the phobos reserve function to pre-allocate array data to use with the 
append operator."""

I presume this means 
http://dlang.org/phobos/std_array.html#.Appender.reserve but how `append` is 
considered an operator is beyond me.

Anyhow, is `reserve` the only thing that makes this more efficient? How is 
this more efficient than setting the .length of the dynamic array directly? 
I see there's a lot of logic going into ensureAddable() but doesn't this 
logic happen within druntime for the regular dynamic arrays itself?

-- 
Shriramana Sharma, Penguin #395953 


Re: `clear`ing a dynamic array

2015-10-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, October 25, 2015 17:15:50 Shriramana Sharma via Digitalmars-d-learn 
wrote:
> Jonathan M Davis via Digitalmars-d-learn wrote:
>
> > Appender really isn't intended to be used as a
> > container - just as a way to make appending more efficient or to have an
> > output range which is an array
>
> I get the part about Appender helping to make an output range of a regular
> array, but I'm not sure how it is supposed to make appending "more
> efficient". I just had a look at the std.array code for appender and
> couldn't figure what was so special – obviously it's my limited knowledge.

There is bookkeeping in the GC involved with appending to a dynamic array
(e.g. it has to look up whether there is room to grow into the buffer that
backs the dynamic array or even whether the dynamic array is even backed by
a GC-allocated buffer at all). Appender takes advantage of the fact that
it's designed specifically for appending and keeps track of certain things
on its own, bypassing a lot of what ~= normally does in an effort to make
the specific use case of appending a bunch of times in a row efficient. So,
it bypasses a lot of the checks that ~= is normally forced to do, but the
result is that it's really just for constructing an array up front, whereas
~= can be used whenever, and I'm not sure that Appender even works correctly
if you do something like get the array from it and start operating on it
separately from the Appender and then continue to use the Appender. Really,
you're supposed to use it to fill the array with its initial values, get the
array out of the Appender, and then stop using the Appender.

- Jonathan M Davis




Re: `clear`ing a dynamic array

2015-10-25 Thread Jonathan M Davis via Digitalmars-d-learn
On Sunday, October 25, 2015 16:23:14 Shriramana Sharma via Digitalmars-d-learn 
wrote:
> Thanks all, for your replies.
>
> Jonathan M Davis via Digitalmars-d-learn wrote:
>
> > If you want a container rather than a dynamic array - especially if you're
> > looking for full reference semantics - then use std.container.array.Array.
>
> Hmmm, pardon me but while I'm sure I don't specifically require reference
> semantics, I'm not sure how you mean to contrast a "container" vs a "dynamic
> array". Both are aware of their content count and both are iterable, no? Is
> it that by "container" you mean that something that owns its contents and is
> responsible for deleting them all when it itself is deleted?

Dynamic arrays are really pseudo-containers. They do not own or manage their
own memory, and their memory and elements are potentially shared across
multiple dynamic arrays. And mutating one dynamic array does not normally
affect another one - even if they refer to the same memory - unless you're
mutating its elements, and if one of them ends up having to be reallocated
(e.g. because there wasn't enough room to append another element when an
append operation was attempted), then two dynamic arrays which referred to
the same memory would then refer to completely different memory.

You started out this thread talking about how you wanted to be able to
"clear" a dynamic array and have that affect other dynamic arrays which
referred to the same memory, and that doesn't make any sense with a dynamic
array, because dynamic arrays are not full reference types. They share the
memory that they point to, but mutating the length of one (either directly
or by adding or removing elements) does not affect any other dynamic array
(except insofar as it can affect when an array would have to have its memory
reallocated). That's why I talked about reference semantics.

If you want a container that you pass around where removing an element from
it or adding an element to it affects all of the other variables referring
to that same data, you need an actual container type, not a dynamic array.

If you haven't read this article yet

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

I'd suggest that you do. The terminology that it uses does not match the
offial terminology (e.g. per the spec, T[] is a dynamic array regardless of
what memory backs it, whereas that article refers to the GC-allocated buffer
that backs most dynamic arrays as being the dynamic array), but it should
make the semantics of D's dynamic arrays much clearer.

- Jonathan M Davis



Re: `clear`ing a dynamic array

2015-10-25 Thread Shriramana Sharma via Digitalmars-d-learn
anonymous wrote:

>> I presume this means
>> http://dlang.org/phobos/std_array.html#.Appender.reserve but
>> how `append` is considered an operator is beyond me.
> 
> That sentence doesn't refer to std.array.Appender. `reserve`
> means . The append
> operator is `~=`.

Thanks for that clarification. Now submitted a pull request.

-- 
Shriramana Sharma, Penguin #395953


Re: `clear`ing a dynamic array

2015-10-24 Thread anonymous via Digitalmars-d-learn

On 24.10.2015 15:18, Shriramana Sharma wrote:

   int a[] = [1,2,3,4,5];


Aside: `int[] a;` is the preferred style for array declarations.


How to make it so that after clearing `a`, `b` will also point to the same
empty array? IOW the desired output is:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[]

... and any further items added to `a` should also reflect in `b`.



You can't do that with built-in arrays. The length of a dynamic array is 
a value member of the array structure. So to update `b`'s length you 
need access to the actual `b`.




Re: `clear`ing a dynamic array

2015-10-24 Thread Cauterite via Digitalmars-d-learn
I'm afraid what you're asking for is impossible. Because 'a' and 
'b' are both slices, they each have their own 'length' field. 
When you do 'a = []', you're effectively doing 'a.length = 0'. 
There's no way to change 'b.length' through 'a'. To get that 
effect, you'd have to do something like this:

int[] a = [1,2,3,4,5];
int[]* b = 
a = [];
assert(*b == [] && b.length == 0);

On Saturday, 24 October 2015 at 13:18:26 UTC, Shriramana Sharma 
wrote:
Hello. I had first expected that dynamic arrays (slices) would 
provide a `.clear()` method but they don't seem to. Obviously I 
can always effectively clear an array by assigning an empty 
array to it, but this has unwanted consequences that `[]` 
actually seems to allocate a new dynamic array and any other 
identifiers initially pointing to the same array will still 
show the old contents and thus it would no longer test true for 
`is` with this array. See the following code:


import std.stdio;
void main()
{
  int a[] = [1,2,3,4,5];
  int b[] = a;
  writeln(a);
  writeln(b);
  //a.clear();
  a = [];
  writeln(a);
  writeln(b);
}

which outputs:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[1, 2, 3, 4, 5]

How to make it so that after clearing `a`, `b` will also point 
to the same empty array? IOW the desired output is:


[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[]

... and any further items added to `a` should also reflect in 
`b`.





Re: `clear`ing a dynamic array

2015-10-24 Thread rsw0x via Digitalmars-d-learn
On Saturday, 24 October 2015 at 13:18:26 UTC, Shriramana Sharma 
wrote:
Hello. I had first expected that dynamic arrays (slices) would 
provide a `.clear()` method but they don't seem to. Obviously I 
can always effectively clear an array by assigning an empty 
array to it, but this has unwanted consequences that `[]` 
actually seems to allocate a new dynamic array and any other 
identifiers initially pointing to the same array will still 
show the old contents and thus it would no longer test true for 
`is` with this array. See the following code:


[...]


use std.container.array


`clear`ing a dynamic array

2015-10-24 Thread Shriramana Sharma via Digitalmars-d-learn
Hello. I had first expected that dynamic arrays (slices) would provide a 
`.clear()` method but they don't seem to. Obviously I can always effectively 
clear an array by assigning an empty array to it, but this has unwanted 
consequences that `[]` actually seems to allocate a new dynamic array and 
any other identifiers initially pointing to the same array will still show 
the old contents and thus it would no longer test true for `is` with this 
array. See the following code:

import std.stdio;
void main()
{
  int a[] = [1,2,3,4,5];
  int b[] = a;
  writeln(a);
  writeln(b);
  //a.clear();
  a = [];
  writeln(a);
  writeln(b);
}

which outputs:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[1, 2, 3, 4, 5]

How to make it so that after clearing `a`, `b` will also point to the same 
empty array? IOW the desired output is:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[]

... and any further items added to `a` should also reflect in `b`. 

-- 
Shriramana Sharma, Penguin #395953


Re: `clear`ing a dynamic array

2015-10-24 Thread John Colvin via Digitalmars-d-learn
On Saturday, 24 October 2015 at 13:18:26 UTC, Shriramana Sharma 
wrote:
Hello. I had first expected that dynamic arrays (slices) would 
provide a `.clear()` method but they don't seem to. Obviously I 
can always effectively clear an array by assigning an empty 
array to it, but this has unwanted consequences that `[]` 
actually seems to allocate a new dynamic array and any other 
identifiers initially pointing to the same array will still 
show the old contents and thus it would no longer test true for 
`is` with this array. See the following code:


import std.stdio;
void main()
{
  int a[] = [1,2,3,4,5];
  int b[] = a;
  writeln(a);
  writeln(b);
  //a.clear();
  a = [];
  writeln(a);
  writeln(b);
}

which outputs:

[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[1, 2, 3, 4, 5]

How to make it so that after clearing `a`, `b` will also point 
to the same empty array? IOW the desired output is:


[1, 2, 3, 4, 5]
[1, 2, 3, 4, 5]
[]
[]

... and any further items added to `a` should also reflect in 
`b`.


D's arrays are not pure reference types, they work like `struct 
Array(T) { size_t length; T* ptr; }` with some extra methods and 
operators. If you think of them like that it should be clear what 
is/isn't possible.


If you want to have two references to the same array, including 
the length, use T[]* or a ref argument to a function or wrap it 
in a class.


Re: `clear`ing a dynamic array

2015-10-24 Thread Shriramana Sharma via Digitalmars-d-learn
rsw0x wrote:

> use std.container.array

Thanks all for all the recommendations. When would one use 
std.array.appender with a built-in array vs std.container.array.Array? What 
are the pros and cons on either side?

-- 
Shriramana Sharma, Penguin #395953