Range Redesign: Empty Ranges

Steven Schveighoffer schveiguy at gmail.com
Wed Mar 6 16:47:02 UTC 2024


On Wednesday, 6 March 2024 at 14:18:50 UTC, Paul Backus wrote:
> On Monday, 4 March 2024 at 21:29:40 UTC, Jonathan M Davis wrote:
>> 2. The range API provides no way (other than fully iterating 
>> through a range) to get an empty range of the same type from a 
>> range unless the range is a random-access range.
>
> Genuine question: what are the use-cases for this?
>
> In general, the capabilities of ranges are designed to serve 
> the needs of algorithms. Input ranges exist because single-pass 
> iteration is all that's needed to implement algorithms like 
> map, filter, and reduce. Random-access ranges exist because 
> they're needed for sorting algorithms. And so on.
>
> I'm not aware of any algorithm, or class of algorithm, that 
> needs this specific capability you're describing. If such 
> algorithms exist, we should be using them to guide our design 
> here. If they don't...then maybe this isn't really a problem at 
> all.

When you need to pass a specific range type, and you want to pass 
in an empty range of that type, how do you do it? There is no 
formal definition for "create an empty range T". It's not just 
algorithms, it's regular functions or types with specific 
parameter requirements.

What is a very logical mechanism is just to pass the `init` 
value, because 99% of the time, that is the same thing as an 
empty range. Except when it isn't. But if you aren't testing for 
that, then you don't realize it. Or if code changes slightly such 
that now you involve a range you didn't before which doesn't have 
that property, then all of a sudden code breaks.

We can add a new requirement that ranges that can be initialized 
as empty have some `emptyRange` static member or something like 
that. But I expect this is going to go down the same route as 
`save`, where really you should be calling `save` every time you 
copy a forward range, but in practice nobody does, since regular 
copying is 99% of the time the same thing. Likewise people will 
pass `.init` instead of `.emptyRange` because it's almost always 
the same thing. This is why I think it should just be formally 
stated that the `init` value of a non-infinite range should be 
empty, bringing into standard what people *already do*.

The only tricky aspect is ranges that are references 
(classes/pointers). Neither of those to me should be supported 
IMO, you can always wrap such a thing in a range harness.

But if people insist that we must have class ranges, I'd say an 
`emptyRange` property is in order.

-Steve


More information about the Digitalmars-d mailing list