Range Redesign: Copy Semantics

Quirin Schroll qs.il.paperinik at gmail.com
Tue Jan 23 15:55:01 UTC 2024


On Sunday, 21 January 2024 at 14:51:33 UTC, Paul Backus wrote:
> On Sunday, 21 January 2024 at 05:00:31 UTC, Jonathan M Davis 
> wrote:
>> From what I can see, the main negative is simply that you 
>> can't then write code that works on both a basic input range 
>> and a forward range (though you can obviously still create 
>> function overloads so that the caller can use either)
>
> With the proposed design, it would be possible to implement 
> next() for forward ranges as a UFCS function:
>
>     auto next(FR)(FR fr)
>         if (std.v2.range.isForwardRange!FR)
>     {
>         if (fr.empty)
>         {
>             return Nullable!(ElementType!FR).init;
>         }
>         else
>         {
>             scope(success) fr.popFront;
>             return nullable(fr.front);
>         }
>     }
>
> So, a function written to operate on basic input ranges would 
> be able to accept any kind of range, same as today.

It wouldn’t work. That’s the point. It would compile, probably, 
but by the proposal, an input range would have guaranteed 
reference semantics, whereas a forward range has value semantics 
(as far as iteration state is concerned). That means, if you call 
`next` on a copy of an input range, *both* ranges, the old one 
and the copy, are on the following element, but doing that on a 
forward range, only the copy would be on the next element and the 
original would not. Both guaranteed.

I’d rather say that a forward range must have a `@disable`d 
`next`, i.e. `isForwardRange` should test if `next` is present 
and if it is, refuse to acknowledge the forward range. By the 
proposal, input and forward ranges are fundamentally 
incommensurate concepts on the usage side; granted, only when it 
comes to copying, but that’s enough.


More information about the Digitalmars-d mailing list