How is chunkBy supposed to behave on copy

Steven Schveighoffer schveiguy at gmail.com
Wed Mar 18 16:18:04 UTC 2020


On 3/18/20 10:57 AM, Dukc wrote:
> ```
> void main()
> {    import std;
>      auto chunks = [14, 16, 18, 20, 22, 20, 18, 16]
>      .chunkBy!((a, b) => a / 10 == b / 10);
> 
>      //[[14, 16, 18], [20, 22, 20], [18, 16]]
>      chunks
>      .map!(chunk => chunk.array)
>      .array
>      .writeln;
> 
>      //[]
>      chunks
>      .map!(chunk => chunk.array)
>      .array
>      .writeln;
> }
> ```
> 
> This is how chunkBy[1] currently behaves when copying. It essentially 
> behaves like a reference range: it will only save it's state when `save` 
> is explicitly called, not otherwise, even if the chunked source range is 
> a forward range with value semantics.
> 
> As most Phobos ranges preserve the value semantics of their source 
> ranges, this is an odd exception, especially as the documentation says 
> nothing about it.
> 
> So the question is, how should it behave? I have looked at the 
> implementation, it should be trivial to have it to use value semantics. 
> On the oher hand, someone may rely on the present behaviour.
> 
> [1] https://dlang.org/phobos/std_algorithm_iteration.html#.chunkBy

According to the range spec, save must be called if you wish to preserve 
state.

In practice, this is seldom done, because most of the time, save just 
does `return this;`, so copying works just the same.

The short answer is, use save.

The long answer is, rangeBy uses reference counting internally to store 
the range data. I'm not sure why this is, as it seems possible to do 
without this mechanism. It seems there is some optimization surrounding 
pushing along the range without iterating it twice. But I don't know if 
that's a worthwhile optimization, especially if the allocation and 
reference counting are more expensive than the iteration.

I would think you could get away with simply storing the range twice, 
and using .save to make sure you don't have problems.

-Steve


More information about the Digitalmars-d mailing list