Recursive vs. iterative constraints

Alex Parrill via Digitalmars-d digitalmars-d at puremagic.com
Fri Apr 15 19:58:16 PDT 2016


On Saturday, 16 April 2016 at 02:42:55 UTC, Andrei Alexandrescu 
wrote:
> So the constraint on chain() is:
>
> Ranges.length > 0 &&
> allSatisfy!(isInputRange, staticMap!(Unqual, Ranges)) &&
> !is(CommonType!(staticMap!(ElementType, staticMap!(Unqual, 
> Ranges))) == void)
>
> Noice. Now, an alternative is to express it as a recursive 
> constraint:
>
> (Ranges.length == 1 && isInputRange!(Unqual!(Ranges[0])))
>   ||
>   (Ranges.length == 2 &&
>     isInputRange!(Unqual!(Ranges[0])) &&
>     isInputRange!(Unqual!(Ranges[1])) &&
>     !is(CommonType!(ElementType!(Ranges[0]), 
> ElementType!(Ranges[1])) == void))
>   || is(typeof(chain(rs[0 .. $ / 2], chain(rs[$ / 2 .. $]))))
>
> In the latter case there's no need for additional helpers but 
> the constraint is a bit more bulky.
>
> Pros? Cons? Preferences?
>
>
> Andrei

The former, definitely.

The only helper function you're getting rid of that I see is 
allSatisfy, which describes the constraint very well. The 
recursive constraint obscures what the intended constraint is 
(that the passed types are input ranges with a common type) 
behind the recursion.


More information about the Digitalmars-d mailing list