of "Conditional Implementation" vs "Assertive Input Validation"

monarch_dodra monarchdodra at gmail.com
Mon Jul 23 13:28:01 PDT 2012


On Monday, 23 July 2012 at 19:57:42 UTC, Jacob Carlborg wrote:
> [snip]
> I know that others have had similar ideas. In these cases I 
> think the compiler should be able to give clear and proper 
> error messages when something fails to match because now the 
> range constraints/interfaces have names. Something like "Foo 
> doesn't match BidirectionalRange" or similar.

My fear is that no matter how you look at it, the compiler just 
doesn't know which overload you want to call. If the compiler 
could generate messages about why each overload was not 
satisfactory, and it would have then to generate messages about 
each and every possible overload, including the ones that you 
obviously didn't want. Things would be better, but probably 
over-verbose :/

My thought was not to remove conditional implementations 
entirely, but rather to compliment them:

I think, for example, this would be perfect for equal:
"Takes two input ranges, and compares them with pred":
Notice that the english input condition here is merely "two input 
ranges". If the range elements don't actually compare, it does 
not mean you did not fulfill the "input contract", but rather 
that you did not fulfill the "implementation requirements".

equal(alias pred = "a == b", R1, R2)(R1 range1, R2 range2)
   if (isInputRange!R1 && isInputRange!R2)
{
   assert(is(typeof(BinaryPred!pred(r1.front, r2.front))), "equal: 
elements are not predicate comparable");
   ...
}

On Monday, 23 July 2012 at 14:47:50 UTC, Andrei Alexandrescu 
wrote:
> The assertive input validation has the problem it prevents an 
> overload outside of std.algorithm from working.
>
> I think we should focus here on the compiler giving better 
> information about which part of the Boolean constraint failed.
>
>
> Andrei
That is true, but then again, a certain level of ambiguity is "a 
good thing"®. The compiler choosing too eagerly which function 
you want to call based on obscure conditional implementations is 
dangerous (IMO).

For example, if somebody else provided an "equal" which operated 
on two input ranges, and took a unary predicated, and then used 
the result of the unary predicate to compare the elements, I sure 
as hell wouldn't it to be disambiguated without my explicit 
consent.

If somebody writes a "fill" that can operate on input 
(non-forward, non-infinite) ranges, I WANT the ambiguity.

----
I think the above gives a good balance of both approaches: The 
conditional implementation is enough to *roughly* define what the 
function operates on, while giving enough leeway for 
non-ambiguous overloads. Once the compiler has *chosen* the 
implementation though, then more thorough input validation can 
kick in.

That's my take on it anyways.


More information about the Digitalmars-d mailing list