Interfaces, traits, concepts, and my idea for a DIP

Atila Neves via Digitalmars-d digitalmars-d at puremagic.com
Thu Jul 30 03:40:57 PDT 2015


On Wednesday, 29 July 2015 at 20:41:02 UTC, Tofu Ninja wrote:
> On Wednesday, 29 July 2015 at 20:26:53 UTC, Tofu Ninja wrote:
>> If you write:
>>
>> @satisfies!(isInputRange, MyRange) struct MyRange { ... }
>>
>> the UDA can check it self, it really works as expected. Which 
>> is why I suggested a way to get whatever the UDA is attached 
>> to automatically in my other post.
>
> A UDA can reference the thing it's being attached to with no 
> problems.
> For example, this works 100% as expected right now...
>
> @UDA!testS struct testS // UDA fails to instantiate because 
> testS is not an inputRange!
> {
> 	
> }
>
> template UDA(alias a)
> {
> 	import std.range;
> 	static assert(isInputRange!a);
> }
>
> The only thing that would be needed to make this a nice 
> solution is some syntax sugar to automatically get whatever the 
> UDA is attached to, which is why I suggested this:
>
> template UDA(alias a = __UDA_ATTACHMENT__) { ... }

You still wouldn't get a better error message here than with:

struct MyRange {
     ...
     static assert(isInputRange!MyRange);
}

It's less typing, but you still wouldn't know why the static 
assertion failed. Now, if we make Adam's idiom in my 
aforementioned pull request the go-to thing, then this would be 
good:

@satisfies!(checkInputRange, MyRange) struct MyRange { ... }

There's still the problem of having two names for each 
constraint: checkInputRange and isInputRange. But... we could 
also establish the convention of checkXXX and use string mixins 
to turn this:

@satifies!(isInputRange, MyRange)

into (which works cos I just tried it):

template satisfies(alias Constraint, R) {
     enum check = "check" ~ Constraint.stringof[2..$-3] ~ "!(R)";
     enum assert_ = "static assert("~ check ~ ");";
     mixin(assert_); //mixes in "static assert(checkInputRange!R)"
}


@satisfies!(isInputRange, Zeroes)
struct Zeroes {
     enum empty = false;
     void popFront() {}
     @property int front() { return 0; }
}


Now, _this_ I could go for.

Atila


More information about the Digitalmars-d mailing list