Range Redesign: Copy Semantics

Paul Backus snarwin at gmail.com
Tue Jan 23 18:21:47 UTC 2024


On Tuesday, 23 January 2024 at 17:25:47 UTC, Steven Schveighoffer 
wrote:
> You are thinking about this the wrong way. Copyability becomes 
> a trait of forward ranges, instead of input ranges. An input 
> range would not be copyable, therefore code which takes input 
> ranges would have to take them by reference, or the caller 
> would have to ensure no other copies exist. But you can still 
> take forward ranges this way.
>
> It is not hard to do -- you just remove the requirement for 
> copying from `isInputRange`, and add it to `isForwardRange`.
>
> [...]
>
> The assertion is that if the range is copyable, it's now a 
> forward range and copying is allowed. It is *on you* as the 
> range developer to ensure copying does not work if it's an 
> input range.

The only problem with this is that what you are asking the range 
developer to do is impossible. :)

Consider what would happen if the user creates a pointer to a 
non-copyable input range.  The pointer (a) is inherently copyable 
and (b) implements the range interface (via implicit 
dereferencing), but (c) the copies are not independent.

(If your response to this is "ok, we'll just have isForwardRange 
explicitly reject pointers", keep in mind that this problem also 
applies to generic wrapper types that use `alias this` or 
`opDispatch`. Are we really going to tell our users that it's 
their fault if their code breaks because they put a range pointer 
inside one of these types?)

So, there has to be some other way of distinguishing forward 
ranges from input ranges, beyond just checking whether they can 
be copied. For example, by using `next()` for input ranges vs. 
`head()`/`tail()` for forward ranges. (As [you pointed out 
earlier][1], reusing the `empty`/`front`/`popFront` API would not 
be a great idea.)

Once you have this other method of distinguishing input and 
forward ranges, requiring forward ranges to be copyable no longer 
implies that pure input ranges MUST be non-copyable. So we can 
allow "pointer-to-input-range" to be an input range itself, even 
though it supports copying, and nothing will break.

[1]: 
https://forum.dlang.org/post/yppqryhpumcucqspkqsx@forum.dlang.org


More information about the Digitalmars-d mailing list