Thread overview | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
|
April 04, 2014 std.array.array seems to return flatten copy of input | ||||
---|---|---|---|---|
| ||||
Hi, I've started using D as a scripting language at work and for personal projects as a means to learn the language and I've bumped into a case where I would like to iterate a slice by a certain number of elements at a time such that : foreach(s; [1,2,3,4].splice!(2)) { writeln(s); } would print : [1,2] [3,4] First of all, is there such a function in D's standard library as I didn't seem to be able to find one ? I ended up implementing the following : import std.stdio; import std.range; import std.array; auto splice( size_t N, R )( R range ) if(isInputRange!R) { struct Splicer { R array; @property bool empty( ) const { return 0 == array.length; } @property auto front( ) const { return array[0 .. N]; } void popFront( ) { array = array[N .. $]; } } static assert(isInputRange!Splicer); assert(range.length % N == 0); Splicer res = { range }; return res; } unittest { assert(equal([1,2,3,4].splice!(2), [[1,2],[3,4]])); } void main( ) { auto a = [1,2,3,4]; writeln(a.splice!(2)); writeln(a.splice!(2).array); } which weirdly enough gives me the following output : [[1,2],[3,4]] // I expect that. [1,2,3,4] // But what is happening here ? I'm obviously doing something wrong but I can't figure out what. Thanks for the help in advance, O. |
April 04, 2014 Re: std.array.array seems to return flatten copy of input | ||||
---|---|---|---|---|
| ||||
Posted in reply to Olivier Grant | On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote:
> iterate a slice by a certain number of elements at a time such that :
>
> foreach(s; [1,2,3,4].splice!(2))
> {
> writeln(s);
> }
>
> would print :
>
> [1,2]
> [3,4]
>
> First of all, is there such a function in D's standard library as I didn't seem to be able to find one ?
std.range.chunks
|
April 04, 2014 Re: std.array.array seems to return flatten copy of input | ||||
---|---|---|---|---|
| ||||
Posted in reply to Olivier Grant | On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote: > Hi, > > I've started using D as a scripting language at work and for personal projects as a means to learn the language and I've bumped into a case where I would like to iterate a slice by a certain number of elements at a time such that : > > foreach(s; [1,2,3,4].splice!(2)) > { > writeln(s); > } > > would print : > > [1,2] > [3,4] > > First of all, is there such a function in D's standard library as I didn't seem to be able to find one ? http://dlang.org/phobos/std_range.html#chunks |
April 04, 2014 Re: std.array.array seems to return flatten copy of input | ||||
---|---|---|---|---|
| ||||
Posted in reply to Olivier Grant | On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote:
> import std.stdio;
> import std.range;
> import std.array;
>
> auto splice( size_t N, R )( R range )
> if(isInputRange!R)
> {
> struct Splicer
> {
> R array;
>
> @property bool empty( ) const
> { return 0 == array.length; }
>
> @property auto front( ) const
> { return array[0 .. N]; }
>
> void popFront( )
> { array = array[N .. $]; }
> }
>
> static assert(isInputRange!Splicer);
>
> assert(range.length % N == 0);
>
> Splicer res = { range };
> return res;
> }
>
> unittest
> {
> assert(equal([1,2,3,4].splice!(2), [[1,2],[3,4]]));
> }
>
> void main( )
> {
> auto a = [1,2,3,4];
>
> writeln(a.splice!(2));
> writeln(a.splice!(2).array);
> }
>
> which weirdly enough gives me the following output :
>
> [[1,2],[3,4]] // I expect that.
> [1,2,3,4] // But what is happening here ?
a.splice!(2).array is the field of the Splicer struct. Rename
that or call std.array.array not via UFCS.
|
April 04, 2014 Re: std.array.array seems to return flatten copy of input | ||||
---|---|---|---|---|
| ||||
Posted in reply to anonymous | That is one responsive D community :) Thank you to all three of you for these quick answers.
I was really scratching my head on that one. This shows that UFCS can be quite dangerous. Is there any way to hide Splicer.array to the outside world? It just seems that it would be very easy to break client code by updating your implementation if you end up using a name that is already used elsewhere and accessed using UFCS.
Thanks,
O.
On Friday, 4 April 2014 at 20:29:28 UTC, anonymous wrote:
> On Friday, 4 April 2014 at 20:19:53 UTC, Olivier Grant wrote:
>> import std.stdio;
>> import std.range;
>> import std.array;
>>
>> auto splice( size_t N, R )( R range )
>> if(isInputRange!R)
>> {
>> struct Splicer
>> {
>> R array;
>>
>> @property bool empty( ) const
>> { return 0 == array.length; }
>>
>> @property auto front( ) const
>> { return array[0 .. N]; }
>>
>> void popFront( )
>> { array = array[N .. $]; }
>> }
>>
>> static assert(isInputRange!Splicer);
>>
>> assert(range.length % N == 0);
>>
>> Splicer res = { range };
>> return res;
>> }
>>
>> unittest
>> {
>> assert(equal([1,2,3,4].splice!(2), [[1,2],[3,4]]));
>> }
>>
>> void main( )
>> {
>> auto a = [1,2,3,4];
>>
>> writeln(a.splice!(2));
>> writeln(a.splice!(2).array);
>> }
>>
>> which weirdly enough gives me the following output :
>>
>> [[1,2],[3,4]] // I expect that.
>> [1,2,3,4] // But what is happening here ?
>
> a.splice!(2).array is the field of the Splicer struct. Rename
> that or call std.array.array not via UFCS.
|
April 04, 2014 Re: std.array.array seems to return flatten copy of input | ||||
---|---|---|---|---|
| ||||
Posted in reply to Olivier Grant | On Fri, 04 Apr 2014 16:35:57 -0400, Olivier Grant <against.the@evil.bots.com> wrote:
> That is one responsive D community :) Thank you to all three of you for these quick answers.
>
> I was really scratching my head on that one. This shows that UFCS can be quite dangerous. Is there any way to hide Splicer.array to the outside world? It just seems that it would be very easy to break client code by updating your implementation if you end up using a name that is already used elsewhere and accessed using UFCS.
I advise to call it _array to prevent such issues.
Note, you can make the field private, but that is a module-level directive. In order for it to apply, main would have to be in a separate module.
In that case, the code would simply fail to compile. As a rule, members ALWAYS have precedence over UFCS functions.
-Steve
|
April 04, 2014 Re: std.array.array seems to return flatten copy of input | ||||
---|---|---|---|---|
| ||||
Posted in reply to Olivier Grant | Olivier Grant:
> Is there any way to hide Splicer.array to the outside world?
If your splice is inside another module, and you tag the array field with private, you will receive an error:
auto splice( size_t N, R )( R range )
if(isInputRange!R)
{
struct Splicer
{
private R array;
This avoids your mistake, but also forbids you to use the std.array.array on a splice with UFCS. Is this acceptable for you?
Bye,
bearophile
|
April 04, 2014 Re: std.array.array seems to return flatten copy of input | ||||
---|---|---|---|---|
| ||||
Posted in reply to bearophile | Yes, that definitely seems like a good start. To be honest, I not familiar enough yet with how you are suppose to organise your source code in D.
Is there any agreed-on naming convention when it comes to member variables to avoid that kind of name clash ?
Thanks,
O.
On Friday, 4 April 2014 at 20:44:36 UTC, bearophile wrote:
> Olivier Grant:
>
>> Is there any way to hide Splicer.array to the outside world?
>
> If your splice is inside another module, and you tag the array field with private, you will receive an error:
>
>
> auto splice( size_t N, R )( R range )
> if(isInputRange!R)
> {
> struct Splicer
> {
> private R array;
>
>
> This avoids your mistake, but also forbids you to use the std.array.array on a splice with UFCS. Is this acceptable for you?
>
> Bye,
> bearophile
|
April 05, 2014 Re: std.array.array seems to return flatten copy of input | ||||
---|---|---|---|---|
| ||||
Posted in reply to Steven Schveighoffer | Sorry Steven,
I hadn't seen your answer.
Thanks for the extra information.
O.
On Friday, 4 April 2014 at 20:42:32 UTC, Steven Schveighoffer wrote:
> On Fri, 04 Apr 2014 16:35:57 -0400, Olivier Grant <against.the@evil.bots.com> wrote:
>
>> That is one responsive D community :) Thank you to all three of you for these quick answers.
>>
>> I was really scratching my head on that one. This shows that UFCS can be quite dangerous. Is there any way to hide Splicer.array to the outside world? It just seems that it would be very easy to break client code by updating your implementation if you end up using a name that is already used elsewhere and accessed using UFCS.
>
> I advise to call it _array to prevent such issues.
>
> Note, you can make the field private, but that is a module-level directive. In order for it to apply, main would have to be in a separate module.
>
> In that case, the code would simply fail to compile. As a rule, members ALWAYS have precedence over UFCS functions.
>
> -Steve
|
Copyright © 1999-2021 by the D Language Foundation