New syntax proposal for template type parameter contraints

Idan Arye via Digitalmars-d digitalmars-d at puremagic.com
Fri May 16 18:28:48 PDT 2014


On Saturday, 17 May 2014 at 00:42:35 UTC, Phil Lavoie wrote:
> On Friday, 16 May 2014 at 23:14:13 UTC, Idan Arye wrote:
>> On Friday, 16 May 2014 at 20:31:40 UTC, Phil Lavoie wrote:
>> The main problem is that `myTemplateFunction`'s signature 
>> makes it look like it's a concrete function, when in fact it's 
>> a template.
>
> True. To me that is not a big issue though. It can lead to some 
> surprises I see your point but I would be ok with that.

When I see such a signature as `void myTemplateFunction( 
InputRange!int r ) {` I'm automatically assuming I can do things 
like `void function(InputRange!int) foo = &myTemplateFunction;`, 
but in our case I can't since it's a template. Also, since it's a 
template, certain instantiations might cause it to crash. We have 
come to expect such things from templates, but here we don't 
expect a template.

Also, I'm not very familiar with the internals of the parser, but 
I'm pretty sure that not being able to tell if a declaration is a 
template or not based on it's signature will cause a serious 
headache...


>> Another problem is that we now have to have an argument if we 
>> want to pass a template parameter, which is a serious 
>> limitation.
>
> Not sure I get what you mean. I didn't mean for the old syntax 
> to be abandonned if that makes sense, just to add some sugar to 
> the existing one.

     void myTemplateFunction(){
         InputRange!int r;
         r.doSomething();
     }

When you call `myTemplateFunction`, how do you tell it which 
concrete type that implements `InputRange` to use?

Also:

     void myTemplateFunction(InputRange!int a, InputRange!int 
b){...

Must `a` and `b` share the same type, or can they have two 
different types as long as the two types fulfill `InputRange!int`?


>> How about if instead these constraint could be used in `is` 
>> expressions like type specializations?
>>
>>    void myTemplateFunction(T)(T r) if(is(T : InputRange!int)) {
>>      foreach(elt; r) { ... }
>>    }
>>
>> True, the syntax is less elegant, but it's more flexible, you 
>> can easily tell that it's a template, and you can use the same 
>> syntax in static branching.
>>
>
> It's interesting. But would it warrant a change from the usual 
> syntax, which would probably be:
>
> void myTemplateFunction(T)(T r) if( isInputRange!(T, int)) {
>   foreach(elt; r) { ... }
> }

Not as nearly as different from your proposal!

At any rate, this syntax will not be used THAT much. We can 
create a wrapper template in Phobos that encapsulates any type 
that follows a constraint to create a concrete type that 
delegates ONLY the constraints' methods to the real 
struct/object. That way we can create concrete functions:

     void 
myTemplateFunction(InterfaceTemplateWrapper!(InputRange!int) r) 
{...

That way we can make sure `myTemplateFunction` doesn't use any 
other methods of `r` that don't appear in `InputRange!int` but 
happen to be in the all concrete types we have send to the 
function.


> Hmm do you mean like a struct "implementing" an interface?
>
> struct MagicRange: InputRange {
> ...
> }
>
> Where it's not an actual interface but the compiler would check 
> it against the constraint(s). Which would be nice to make sure 
> that a type follows a given interface, although, as soon as it 
> is used as an InputRange you would know.

Assuming it is used as an InputRange at some template that gets 
instantiated. If you are writing a library there is a chance that 
a lot of your code is templates that only get instantiated when 
the library is used.

Yes, you should have unit tests, but having the type system check 
things is better.


>> BTW - I'm don't think we need a new keyword for this - we can 
>> use `interface template` instead.
>
> Love it! Would "template interface" make more sense?

In `mixin template` the word "template" comes second. Consistency 
is always good, and I see no benefit from breaking it here.


More information about the Digitalmars-d mailing list