Re: ranges reading garbage

2015-02-15 Thread bearophile via Digitalmars-d-learn

John Colvin:

prints things like [0, 4, 5, 1, 1, 1459971595, 1459971596, 2, 
2, 1459971596, 1459971597, 3, 4, 8, 9, 5, 5, 4441427819, 
4441427820, 6, 6, 4441427820, 4441427821, 7] but the output 
isn't consistent, the big numbers change on each run.


Try to replace the only() with:

[y, y+ys.length, y+ys.length+1, y+1]

Like this:


import std.range, std.algorithm, std.stdio;

void foo(in float[] data, in float[] xs, in float[] ys) @safe {
iota(0, data.length, ys.length)
.map!(xBase => iota(xBase, xBase + ys.length - 1)
   .map!(y => [y, y+ys.length, y+ys.length+1, 
y+1])

   .joiner)
.joiner
.writeln;
}

void main() {
foo([1,2,3,4,5,6,7,8], [0.1,0.2], [10,20,30,40]);
}



In Rust the compiler enforces that all stack-allocated data 
doesn't come from dead stack frames. In D you have to be careful 
to avoid doing it. In future this kind of bugs will be hopefully 
avoided by a better tracking of the memory.


I am not sure if http://wiki.dlang.org/DIP69 is able to avoid 
this bug, if it can't, then DIP69 needs to be improved.


Bye,
bearophile


Re: ranges reading garbage

2015-02-15 Thread FG via Digitalmars-d-learn

On 2015-02-15 at 19:43, bearophile wrote:

void foo(in float[] data, in float[] xs, in float[] ys) @safe {
 iota(0, data.length, ys.length)
 .map!(xBase => iota(xBase, xBase + ys.length - 1)
.map!(y => [y, y+ys.length, y+ys.length+1, y+1])
.joiner)
 .joiner
 .writeln;
}

void main() {
 foo([1,2,3,4,5,6,7,8], [0.1,0.2], [10,20,30,40]);
}


Odd... Still something is wrong. It prints:
[0, 4, 5, 1, 1, 5, 6, 2, 2, 6, 7, 3, 4, 8, 9, 5, 5, 5, 6, 6, 6, 6, 7, 7]

instead of this:
[0, 4, 5, 1, 1, 5, 6, 2, 2, 6, 7, 3, 4, 8, 9, 5, 5, 9, 10, 6, 6, 10, 11, 7]


Re: ranges reading garbage

2015-02-15 Thread John Colvin via Digitalmars-d-learn

On Sunday, 15 February 2015 at 18:43:35 UTC, bearophile wrote:

John Colvin:

prints things like [0, 4, 5, 1, 1, 1459971595, 1459971596, 2, 
2, 1459971596, 1459971597, 3, 4, 8, 9, 5, 5, 4441427819, 
4441427820, 6, 6, 4441427820, 4441427821, 7] but the output 
isn't consistent, the big numbers change on each run.


Try to replace the only() with:

[y, y+ys.length, y+ys.length+1, y+1]

Like this:


import std.range, std.algorithm, std.stdio;

void foo(in float[] data, in float[] xs, in float[] ys) @safe {
iota(0, data.length, ys.length)
.map!(xBase => iota(xBase, xBase + ys.length - 1)
   .map!(y => [y, y+ys.length, y+ys.length+1, 
y+1])

   .joiner)
.joiner
.writeln;
}

void main() {
foo([1,2,3,4,5,6,7,8], [0.1,0.2], [10,20,30,40]);
}



In Rust the compiler enforces that all stack-allocated data 
doesn't come from dead stack frames. In D you have to be 
careful to avoid doing it. In future this kind of bugs will be 
hopefully avoided by a better tracking of the memory.


I am not sure if http://wiki.dlang.org/DIP69 is able to avoid 
this bug, if it can't, then DIP69 needs to be improved.


Bye,
bearophile


But std.range.OnlyResult!(size_t, 4) is a value type, I don't see 
where the stack reference is being leaked.


Re: ranges reading garbage

2015-02-15 Thread bearophile via Digitalmars-d-learn

FG:


Odd... Still something is wrong. It prints:
[0, 4, 5, 1, 1, 5, 6, 2, 2, 6, 7, 3, 4, 8, 9, 5, 5, 5, 6, 6, 6, 
6, 7, 7]


instead of this:
[0, 4, 5, 1, 1, 5, 6, 2, 2, 6, 7, 3, 4, 8, 9, 5, 5, 9, 10, 6, 
6, 10, 11, 7]


This is less lazy and gives another result:

import std.range, std.algorithm, std.stdio;

void foo(in float[] data, in float[] xs, in float[] ys) @safe {
iota(0, data.length, ys.length)
.map!(xBase => iota(xBase, xBase + ys.length - 1)
   .map!(y => [y, y+ys.length, y+ys.length+1, 
y+1])

   .join)
.join
.writeln;
}

void main() {
foo([1,2,3,4,5,6,7,8], [0.1,0.2], [10,20,30,40]);
}


What a fun program :-)

Bye,
bearophile


Re: ranges reading garbage

2015-02-15 Thread anonymous via Digitalmars-d-learn

On Sunday, 15 February 2015 at 18:13:44 UTC, John Colvin wrote:

Simplified from something bigger:

import std.range, std.algorithm, std.stdio;

void foo(float[] data, float[] xs, float[] ys)
{
auto indices = iota(0, data.length, ys.length)
.map!(xBase =>
iota(xBase, xBase + ys.length - 1)
.map!(y =>
only(y, y+ys.length, y+ys.length+1, y+1))
.joiner())
.joiner();
writeln(indices);
}

void main()
{
foo([1,2,3,4,5,6,7,8],
[0.1,0.2], [10,20,30,40]);
}

prints things like [0, 4, 5, 1, 1, 1459971595, 1459971596, 2, 
2, 1459971596, 1459971597, 3, 4, 8, 9, 5, 5, 4441427819, 
4441427820, 6, 6, 4441427820, 4441427821, 7] but the output 
isn't consistent, the big numbers change on each run.


Reduced some more:

import std.algorithm, std.stdio;
void main()
{
int ys_length = 4;
auto indices = [0]
.map!(xBase => [0].map!(y => ys_length))
.joiner();
writeln(indices);
}


Re: ranges reading garbage

2015-02-15 Thread anonymous via Digitalmars-d-learn

On Sunday, 15 February 2015 at 19:54:45 UTC, anonymous wrote:

Reduced some more:

import std.algorithm, std.stdio;
void main()
{
int ys_length = 4;
auto indices = [0]
.map!(xBase => [0].map!(y => ys_length))
.joiner();
writeln(indices);
}


And more:

import std.stdio;
struct MapResult(alias fun)
{
@property int front() {return fun();}
@property auto save() {return typeof(this)();}
}
void main()
{
int ys_length = 4;
auto dg = {return MapResult!({return ys_length;})();};
writeln(dg().front); /* 4, correct */
writeln(dg().save.front); /* garbage */
}


Re: ranges reading garbage

2015-02-16 Thread anonymous via Digitalmars-d-learn

On Sunday, 15 February 2015 at 22:38:20 UTC, anonymous wrote:

And more:

import std.stdio;
struct MapResult(alias fun)
{
@property int front() {return fun();}
@property auto save() {return typeof(this)();}
}
void main()
{
int ys_length = 4;
auto dg = {return MapResult!({return ys_length;})();};
writeln(dg().front); /* 4, correct */
writeln(dg().save.front); /* garbage */
}


It's already in bugzilla: 
https://issues.dlang.org/show_bug.cgi?id=9685