Thread overview
Repeat and chunks
Oct 24, 2016
Dorian Haglund
Oct 24, 2016
Saurabh Das
Oct 24, 2016
Saurabh Das
Oct 24, 2016
Meta
Oct 24, 2016
Saurabh Das
Oct 24, 2016
ag0aep6g
Oct 24, 2016
Meta
Oct 24, 2016
ag0aep6g
Oct 25, 2016
Dorian Haglund
October 24, 2016
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 :)

October 24, 2016
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

October 24, 2016
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;
}
October 24, 2016
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.
October 24, 2016
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.
October 24, 2016
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?

October 24, 2016
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
October 24, 2016
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.
October 25, 2016
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.