of "Conditional Implementation" vs "Assertive Input Validation"
xenon325
1 at mail.net
Tue Jul 24 22:30:59 PDT 2012
On Tuesday, 24 July 2012 at 12:50:08 UTC, Jacob Carlborg wrote:
> That will be just a little better. The problem is it will leak
> implementation details. For this to be useful you really need
> to create a template for every condition:
>
> template isFoo (T)
> {
> enum isFoo = is(T == Foo);
> }
>
> void foo (T) (T t) if (isFoo!(T));
>
> If you just do it like this:
>
> void foo (T) (T t) if (is(T == Foo));
>
> Then it will leak the "raw" condition.
hmm, yeah that could be hard for novices
> With my approach the constraint will have a name which should
> result in a lot better error messages.
How is it different from creating a template for every condition
? ;)
Honestly, I don't quite get what's the difference between current
template constraints and ones you're proposing:
// yours
constraint InputRange (Range)
{
alias ElementType!(Range.init) E;
@property bool empty ();
void popFront ();
@property E front ();
}
// std.range
//
https://github.com/D-Programming-Language/phobos/blob/master/std/range.d#L549
template isInputRange(R)
{
enum bool isInputRange = is(typeof(
(inout int _dummy=0)
{
R r = void; /*** how would you express this b.t.w.
? ***/
if (r.empty) {}
r.popFront();
auto h = r.front;
}));
}
on the call site it's as convenient and clear as yours.
On the definition site, yes, syntax maybe is a tad worse,
but it's not *that* bad to require introduction of a new
language construct.
Actually the only thing constraint writer needs to know is that
`is(typeof(<code>))`
means "compiles". All the rest is perfectly clear.
> Think of it like this. You have a function, "foo", taking an
> interface parameter, "Foo":
>
> interface Foo
> {
> void a ();
> void b ();
> void c ();
> }
>
> void foo (Foo f);
>
> You then call the function with an object that does _not_
> implement the function, then you get a proper easily
> understandable error message:
>
> foo(new Object);
>
> Error: Object doesn't implement Foo
>
> What would you think if the error message look like this
> instead:
>
> Error: Object doesn't have the methods:
> void a ();
> void b ();
> void c ();
>
> Now imagine that with a bunch of conditions instead.
>
> void foo (T) (T t) if (__traits(compiles, { T t; t.foo; t.bar;
> }) || is(T : Foo));
>
> Error: template foo does not match any function template,
> constraints values are:
> __traits(compiles, { T t; t.foo; t.bar }) false
> is(T : Foo) false
I think I've addressed these points, let me know if
I can explain it better.
More information about the Digitalmars-d
mailing list