Range Redesign: Empty Ranges

H. S. Teoh hsteoh at qfbox.info
Wed Mar 6 17:57:36 UTC 2024


On Wed, Mar 06, 2024 at 05:43:05PM +0000, Paul Backus via Digitalmars-d wrote:
> On Wednesday, 6 March 2024 at 17:32:17 UTC, H. S. Teoh wrote:
> > Every time this topic comes up, class-based ranges become the
> > whipping boy of range design woes.  Actually, they serve an
> > extremely important role: type erasure, which is critical when you
> > have code like this:
> > 
> > 	auto myRangeFunc(R,S)(R range1, S range2) {
> > 		if (runtimeDecision()) {
> > 			return range1;
> > 		} else {
> > 			return range2;
> > 		}
> > 	}
> > 
> > [...]
> > 
> > Note that you can't use a struct wrapper here, because R and S have
> > different ABIs; the only way to correctly forward range methods to R
> > or S is to use overridden base class methods. IOW, the type erasure
> > of R and S is unavoidable for this code to work.
> 
> This is what std.range.choose [1] is for. Internally, it's implemented
> as a tagged union of R and S.
> 
> [1] https://dlang.org/library/std/range/choose.html

Haha, I knew that one would be brought up.  Unfortunately, it only works
for a very limited subset of use cases. In the above simplified code you
could replace the if-statement with .choose. However, this immediately
falls flat if the decision is made by a switch statement, or nested
if-blocks, or an early exit from a loop.

The problem is that .choose requires that both ranges are constructible
in the same scope that it is called in. In non-trivial code this is
sometimes impossible, as you may be in a decision tree where certain
subranges are only constructed if the condition is true, or may depend
on value types that may not even exist if the condition is not
satisfied.  This makes .choose essentially useless outside of trivial
cases.

Besides, .choose does not type-erase, so in the cases where you want
type erasure it's still no help.


T

-- 
English is useful because it is a mess. Since English is a mess, it maps well onto the problem space, which is also a mess, which we call reality. Similarly, Perl was designed to be a mess, though in the nicest of all possible ways. -- Larry Wall


More information about the Digitalmars-d mailing list