www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Repeat and chunks

reply Dorian Haglund <dorian.haglund gmail.com> writes:
Hey,

The following code crashes with DMD64 D Compiler v2.071.2:

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

int main()
{
   repeat(8, 10).chunks(3).writeln();

   return 0;
}

Error message:

pure nothrow  nogc  safe 
std.range.Take!(std.range.Repeat!(int).Repeat).Take 
std.range.Repeat!(int).Repeat.opSlice(ulong, ulong)

If I replace repeat with iota, or a literal range (like [1, 2 ,3, 
4]), I don't get the crash.

I don't see why I should not be able to use chunks with repeat.
If some property of repeat's range is missing to use chunks, 
shouldn't I get an error message ?

Am I missing something ?

PS: the behavior has been reproduced on someone else computer.

Cheers :)
Oct 24 2016
next sibling parent reply Saurabh Das <saurabh.das gmail.com> writes:
On Monday, 24 October 2016 at 14:25:46 UTC, Dorian Haglund wrote:
 Hey,

 The following code crashes with DMD64 D Compiler v2.071.2:

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

 int main()
 {
   repeat(8, 10).chunks(3).writeln();

   return 0;
 }

 Error message:

 pure nothrow  nogc  safe 
 std.range.Take!(std.range.Repeat!(int).Repeat).Take 
 std.range.Repeat!(int).Repeat.opSlice(ulong, ulong)

 If I replace repeat with iota, or a literal range (like [1, 2 
 ,3, 4]), I don't get the crash.

 I don't see why I should not be able to use chunks with repeat.
 If some property of repeat's range is missing to use chunks, 
 shouldn't I get an error message ?

 Am I missing something ?

 PS: the behavior has been reproduced on someone else computer.

 Cheers :)
This works: repeat(8, 12).chunks(3).writeln; The documentation of https://dlang.org/phobos/std_range.html#.chunks mentions something about evenly divisible by chunkSize – perhaps that is the cause of the assert fail. Not 100% sure why that's there though. Thanks, Saurabh
Oct 24 2016
next sibling parent Saurabh Das <saurabh.das gmail.com> writes:
On Monday, 24 October 2016 at 15:28:50 UTC, Saurabh Das wrote:
 On Monday, 24 October 2016 at 14:25:46 UTC, Dorian Haglund 
 wrote:
 Hey,

 The following code crashes with DMD64 D Compiler v2.071.2:

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

 int main()
 {
   repeat(8, 10).chunks(3).writeln();

   return 0;
 }

 Error message:

 pure nothrow  nogc  safe 
 std.range.Take!(std.range.Repeat!(int).Repeat).Take 
 std.range.Repeat!(int).Repeat.opSlice(ulong, ulong)

 If I replace repeat with iota, or a literal range (like [1, 2 
 ,3, 4]), I don't get the crash.

 I don't see why I should not be able to use chunks with repeat.
 If some property of repeat's range is missing to use chunks, 
 shouldn't I get an error message ?

 Am I missing something ?

 PS: the behavior has been reproduced on someone else computer.

 Cheers :)
This works: repeat(8, 12).chunks(3).writeln; The documentation of https://dlang.org/phobos/std_range.html#.chunks mentions something about evenly divisible by chunkSize – perhaps that is the cause of the assert fail. Not 100% sure why that's there though. Thanks, Saurabh
Some more cases, perhaps someone more knowledgeable can help: import std.algorithm; import std.stdio; import std.range; int main() { [8, 8, 8, 8, 8, 8].chunks(3).writeln; // prints [[8, 8, 8], [8, 8, 8]] repeat(8, 6).writeln; // prints [8, 8, 8, 8, 8, 8] repeat(8, 6).chunks(3).writeln; // prints [[8, 8, 8]]. Why? assert([8, 8, 8, 8, 8, 8] == repeat(8, 6).array); // Passes assert([8, 8, 8, 8, 8, 8].chunks(3).array == repeat(8, 6).array.chunks(3).array); // Passes assert([8, 8, 8, 8, 8, 8].chunks(3).array == repeat(8, 6).chunks(3).map!(a => a.array).array); // Fails return 0; }
Oct 24 2016
prev sibling parent reply Meta <jared771 gmail.com> writes:
On Monday, 24 October 2016 at 15:28:50 UTC, Saurabh Das wrote:
 The documentation of 
 https://dlang.org/phobos/std_range.html#.chunks mentions 
 something about evenly divisible by chunkSize – perhaps that is 
 the cause of the assert fail. Not 100% sure why that's there 
 though.

 Thanks,
 Saurabh
Yes, that's correct. This is the overload of `repeat` in question: https://dlang.org/phobos/std_range.html#.repeat.2 Take!(Repeat!T) repeat(T)(T value, size_t n); Repeats value exactly n times. Equivalent to take(repeat(value), n). Examples: import std.algorithm : equal; assert(equal(5.repeat(4), 5.repeat().take(4))); The variant of repeat that takes a second argument returns a range with a length; it is not an infinite range, unlike the first overload of repeat. So for the OP's code: repeat(8, 10).chunks(3).writeln(); This will throw an AssertError because 10 is not evenly divisible by 3.
Oct 24 2016
next sibling parent Saurabh Das <saurabh.das gmail.com> writes:
On Monday, 24 October 2016 at 15:59:05 UTC, Meta wrote:
 On Monday, 24 October 2016 at 15:28:50 UTC, Saurabh Das wrote:
 [...]
Yes, that's correct. This is the overload of `repeat` in question: https://dlang.org/phobos/std_range.html#.repeat.2 Take!(Repeat!T) repeat(T)(T value, size_t n); Repeats value exactly n times. Equivalent to take(repeat(value), n). Examples: import std.algorithm : equal; assert(equal(5.repeat(4), 5.repeat().take(4))); The variant of repeat that takes a second argument returns a range with a length; it is not an infinite range, unlike the first overload of repeat. So for the OP's code: repeat(8, 10).chunks(3).writeln(); This will throw an AssertError because 10 is not evenly divisible by 3.
Sure, but: // This fails: repeat(8, 9).chunks(3).writeln(); // This works: repeat(8, 6).chunks(3).writeln(); Both are divisible by 3. Maybe it's a bug?
Oct 24 2016
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
On 10/24/2016 05:59 PM, Meta wrote:
 repeat(8, 10).chunks(3).writeln();

 This will throw an AssertError because 10 is not evenly divisible by 3.
chunks doesn't require that the length of the range be evenly divisible by the chunk size. See https://dlang.org/phobos/std_range.html#.Chunks
Oct 24 2016
parent Meta <jared771 gmail.com> writes:
On Monday, 24 October 2016 at 16:17:03 UTC, ag0aep6g wrote:
 On 10/24/2016 05:59 PM, Meta wrote:
 repeat(8, 10).chunks(3).writeln();

 This will throw an AssertError because 10 is not evenly 
 divisible by 3.
chunks doesn't require that the length of the range be evenly divisible by the chunk size. See https://dlang.org/phobos/std_range.html#.Chunks
Huh, you're right. I must've misread. My mistake.
Oct 24 2016
prev sibling parent reply ag0aep6g <anonymous example.com> writes:
On 10/24/2016 04:25 PM, Dorian Haglund wrote:
 The following code crashes with DMD64 D Compiler v2.071.2:

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

 int main()
 {
   repeat(8, 10).chunks(3).writeln();

   return 0;
 }
Looks like a bug. Doesn't happen with 2.072.0-b2, so it has apparently already been fixed.
Oct 24 2016
parent Dorian Haglund <dorian.haglund gmail.com> writes:
On Monday, 24 October 2016 at 16:09:44 UTC, ag0aep6g wrote:
 On 10/24/2016 04:25 PM, Dorian Haglund wrote:
 The following code crashes with DMD64 D Compiler v2.071.2:

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

 int main()
 {
   repeat(8, 10).chunks(3).writeln();

   return 0;
 }
Looks like a bug. Doesn't happen with 2.072.0-b2, so it has apparently already been fixed.
Ok! I'll wait for the next release then. Thanks.
Oct 25 2016