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

Atila Neves via Digitalmars-d digitalmars-d at puremagic.com
Fri Jul 31 07:24:56 PDT 2015


On Friday, 31 July 2015 at 14:23:28 UTC, Atila Neves wrote:
> On Friday, 31 July 2015 at 11:16:48 UTC, Biotronic wrote:
>> On Thursday, 30 July 2015 at 10:40:59 UTC, Atila Neves wrote:
>>> [...]
>>
>> Why are there two different things in the first place?
>>
>> @satisfies!(myConcept, T) should test the constraints and give 
>> a sensible error message. This you use to indicate that type T 
>> implements myConcept.
>>
>> Why can't another template use the very same concept 
>> information to check if a type implements the concept?
>>
>> e.g.:
>>
>> @satisfies!(myConcept, MyStruct)
>> struct MyStruct { /* ... */ }
>>
>> void foo(T)(T t) if (check!(myConcept, T))
>> { /* ... */ }
>
> Because you want to:
>
> 1. Check your type and get sensible error messages
> 2. Use a constraint in function declarations
>
> You can't have `@satisfies!(isInputRange, T)` give you an error 
> message if it doesn't have access to the source code of the 
> lambda that actually does the checking and you can't get error 
> messages unless you force the compilation of code you _know_ 
> won't compile.
>
> It's ok for template constraints to be false without causing a 
> compilation error; that's how we get compile-time template 
> function resolution. When you're using something like 
> `@satisfies` however, you want a compilation error and its 
> message. That's why you need two things.
>
> Atila

Notice however, that (again, in the PR), the "real" definition 
happens only once, in the check function. Then the constraint is 
always a trivial `enum MyConstraint = 
is(typeof(myCheckFunction));`. It's just a matter of moving the 
lambda away, giving it a name, and doing the weird `if(!__ctfe)` 
hack.

Atila


More information about the Digitalmars-d mailing list