Thread overview
parameter type tuple or alias for std.traits templates ?
Jun 22, 2012
Guillaume Chatelet
Jun 22, 2012
Timon Gehr
Jun 23, 2012
Guillaume Chatelet
Jun 23, 2012
Jacob Carlborg
Jun 23, 2012
Timon Gehr
Jun 24, 2012
Philippe Sigaud
Jun 23, 2012
Guillaume Chatelet
June 22, 2012
While reading the source code of std.traits I came across a bunch of variadic templates enforcing the length of their parameter type tuple to be of 1.

Is there any semantic difference between
> template ReturnType(func...) if (func.length == 1 && isCallable!func)
and
> template ReturnType(alias func) if (isCallable!func)

If not, is there any reason why this syntax is used ?

Guillaume
--
The list of templates from std.traits ( https://github.com/D-Programming-Language/phobos/blob/master/std/traits.d ) matching this pattern :

template ReturnType(func...)
 if (func.length == 1 && isCallable!func)

template ParameterTypeTuple(func...)
 if (func.length == 1 && isCallable!func)

template ParameterStorageClassTuple(func...)
 if (func.length == 1 && isCallable!func)

template functionAttributes(func...)
 if (func.length == 1 && isCallable!func)

template functionLinkage(func...)
 if (func.length == 1 && isCallable!func)

template variadicFunctionStyle(func...)
 if (func.length == 1 && isCallable!func)

template FunctionTypeOf(func...)
 if (func.length == 1 && isCallable!func)

template isFunctionPointer(T...)
 if (T.length == 1)

template isDelegate(T...)
 if(T.length == 1)

template isSomeFunction(T...)
 if (T.length == 1)

template isCallable(T...)
 if (T.length == 1)

template isAbstractFunction(method...)
 if (method.length == 1)

template mangledName(sth...)
 if (sth.length == 1)
June 22, 2012
On 06/22/2012 11:50 PM, Guillaume Chatelet wrote:
> While reading the source code of std.traits I came across a bunch of
> variadic templates enforcing the length of their parameter type tuple to
> be of 1.
>
> Is there any semantic difference between
>> template ReturnType(func...) if (func.length == 1&&  isCallable!func)
> and
>> template ReturnType(alias func) if (isCallable!func)
>

Yes there is, but I have argued that this is a bug in the past. With DMD, the (func...) accepts built-in types, while the (alias func) does
not.


> If not, is there any reason why this syntax is used ?
>
> Guillaume
> --

June 23, 2012
On 06/23/12 01:05, Timon Gehr wrote:
> 
> Yes there is, but I have argued that this is a bug in the past. With
> DMD, the (func...) accepts built-in types, while the (alias func) does
> not.

Ok got it, the following won't compile I agree.

template isInt(alias T) {
	enum bool isInt = is(T==int);
}

void main(){
	static assert(isInt!int);
}

So I understand the following functions have to go the variadic way
because you want an answer at compile time and not a compiler error
template isFunctionPointer(T...)
template isDelegate(T...)
template isSomeFunction(T...)
template isCallable(T...)
template isAbstractFunction(method...)
template mangledName(sth...)

Nevertheless the following templates are all requiring 'func.length == 1 && isCallable!func'

template ReturnType(func...)
template ParameterTypeTuple(func...)
template ParameterStorageClassTuple(func...)
template functionAttributes(func...)
template functionLinkage(func...)
template variadicFunctionStyle(func...)
template FunctionTypeOf(func...)

So they won't instantiate if you pass a built-in type anyway. Using an
'alias' instead of a 'func...' would make it clear that :
* you can't pass a built-in type in
* the template is requiring exactly one argument

As a user, I find it odd that ReturnType takes a TypeTuple rather than
an alias. 'func...' basically means 'I will accept a tuple of functions'
which is then restricted in the if clause to the case where func.length==1.

--
Guillaume
June 23, 2012
On 2012-06-23 01:05, Timon Gehr wrote:

> Yes there is, but I have argued that this is a bug in the past. With
> DMD, the (func...) accepts built-in types, while the (alias func) does
> not.

Would it be possible to overload? Something like this:

template Foo (T) {}

template Foo (alias a) {}

-- 
/Jacob Carlborg
June 23, 2012
I'm reposting this because I'm not sure it made it to the NG ( it doesn't show up in the web interface )

On 06/23/12 01:05, Timon Gehr wrote:
> Yes there is, but I have argued that this is a bug in the past. With
> DMD, the (func...) accepts built-in types, while the (alias func) does
> not.

Ok got it, the following won't compile I agree.

template isInt(alias T) {
	enum bool isInt = is(T==int);
}

void main(){
	static assert(isInt!int);
}

So I understand the following functions have to go the variadic way
because you want an answer at compile time and not a compiler error
template isFunctionPointer(T...)
template isDelegate(T...)
template isSomeFunction(T...)
template isCallable(T...)
template isAbstractFunction(method...)
template mangledName(sth...)

Nevertheless the following templates are all requiring 'func.length == 1 && isCallable!func'

template ReturnType(func...)
template ParameterTypeTuple(func...)
template ParameterStorageClassTuple(func...)
template functionAttributes(func...)
template functionLinkage(func...)
template variadicFunctionStyle(func...)
template FunctionTypeOf(func...)

So they won't instantiate if you pass a built-in type anyway. Using an
'alias' instead of a 'func...' would make it clear that :
* you can't pass a built-in type in
* the template is requiring exactly one argument

As a user, I find it odd that ReturnType takes a TypeTuple rather than
an alias. 'func...' basically means 'I will accept a tuple of functions'
which is then restricted in the if clause to the case where func.length==1.

--
Guillaume

June 23, 2012
On 06/23/2012 12:52 PM, Jacob Carlborg wrote:
> On 2012-06-23 01:05, Timon Gehr wrote:
>
>> Yes there is, but I have argued that this is a bug in the past. With
>> DMD, the (func...) accepts built-in types, while the (alias func) does
>> not.
>
> Would it be possible to overload? Something like this:
>
> template Foo (T) {}
>
> template Foo (alias a) {}
>

alias should just accept built in types.
June 24, 2012
Le 23 juin 2012 12:53, "Jacob Carlborg" <doob@me.com> a écrit :
>
> On 2012-06-23 01:05, Timon Gehr wrote:
>
>> Yes there is, but I have argued that this is a bug in the past. With
>> DMD, the (func...) accepts built-in types, while the (alias func) does
>> not.
>
>
> Would it be possible to overload? Something like this:
>
> template Foo (T) {}
>
> template Foo (alias a) {}

I think it is. IIRC, I did something like this.

But then the trouble is with user-defined types: they are both a type and a symbol, so they may fire both templates.