On 11/3/21 11:03 AM, Andrei Alexandrescu wrote:
>On 2021-11-02 19:07, Paul Backus wrote:
>On Tuesday, 2 November 2021 at 21:58:20 UTC, Andrei Alexandrescu wrote:
>On 2021-11-02 17:44, Dukc wrote:
> >What's a value range?
Opposite of a reference range - copying implies save()
.
Yah, one simple improvement we could make is to assume all forward ranges copy their iteration state when copying the range. Then input ranges do NOT do that, i.e. all copies of an input range refer to the same stream and iterate it together (advancing one advances all).
The differentiation can be made with a nested enum tag:
struct MyInputRange {
enum inputRangeTag = true;
...
}
Client code can inspect R.inputRangeTag to figure whether the range is input (if present) or forward (if missing).
Not sure this is the best idea--it means new-style algorithms will silently treat old-style input ranges as though they were forward ranges, which could lead to incorrect behavior at runtime. If we are going to make incompatible changes to the range API, we should do it in such a way that version mismatches are caught at compile time.
Good point. Maybe have all ranges define that enum with values true and false respectively?
Yes, this is what I was trying to point out in my other post.
One thing that is possible is to change at least one of the methods (i.e. change the name of front
, popFront
, or empty
), so it is easy to distinguish a v2 range from a v1 range. An enum works too, and I'd support that.
For sure, you need an opt-in for forward ranges because input ranges are the most basic type.
Thinking about this some more, maybe an enum is better for another reason. One thing we use introspection for but can bite us is to see if something supports a specific interface. But what happens when what we expect is not what actually happens? The result is usually very confusing messages, or introspection that doesn't result in what we expect it to (i.e. some wrapper of our expected forward range only ends up being an input range).
Doing the check for what type of range it is different from the actual code expectations would not only read more cleanly (and perform better I think), it would push the error to the code itself. e.g. you define what you think is a random access range, you specify enum rangeType = RangeType.RandomAccess
as a member, but forget to define opIndex
. Instead of the range just being inferred as non-random-access in some other part of code, the compiler tells you error, cannot call opIndex on type MyRange
, which gives you the exact error you need to fix the problem.
-Steve