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.