Thread overview
Function signature testing with is expression.
Dec 17
ag0aep6g
December 17
Hi,

Have someone tried to test a function against a signature using is expression?

Suppose:
--------
struct F {
    static void foo(T)(T i, int o) {}
}

enum bool check(T) = is(F.foo!T == void function(Z, int), Z);

enum correct = check!int;
--------

Upon running it will return false, though, by logic is expression could deduce that F.foo is conformat to function signature in check test.

It is interesting that it will not work with global functions as well:

--------
void foo(int i, double d) {};
enum bool check = is(typeof(foo) == void function(int, double));
--------

It will be as well evaluated to false.

So, the question is, is it I'm doing something wrong, that it doesn't work, or is it not implemented?
If not implemented, what simple and short alternatives are available?

Thanks.
December 17
On 12/17/2017 06:44 AM, Alexandru Ermicioi wrote:

> It is interesting that it will not work with global functions as well:
>
> --------
> void foo(int i, double d) {};
> enum bool check = is(typeof(foo) == void function(int, double));
> --------

There, the address-of operator is missing. This works:

void foo(int i, double d) {};
static assert(is(typeof(&foo) == void function(int, double)));

Ali

December 17
On Sunday, 17 December 2017 at 14:44:15 UTC, Alexandru Ermicioi wrote:
> Suppose:
> --------
> struct F {
>     static void foo(T)(T i, int o) {}
> }
>
> enum bool check(T) = is(F.foo!T == void function(Z, int), Z);
>
> enum correct = check!int;
> --------
>
> Upon running it will return false, though, by logic is expression could deduce that F.foo is conformat to function signature in check test.

Here, `F.foo!T` is the function itself, not its type. You forgot `typeof`.

> It is interesting that it will not work with global functions as well:
>
> --------
> void foo(int i, double d) {};
> enum bool check = is(typeof(foo) == void function(int, double));
> --------
>
> It will be as well evaluated to false.

Write `typeof(&foo)` to make it work.

There are two kinds of function types in D:

1) "Proper" function types, e.g. `typeof(foo)` which gets printed as "void(int i, double d)", and
2) function pointer types, e.g. `typeof(&foo)` which gets printed as "void function(int i, double d)".

As you see, the second kind is the one you're comparing against. I don't think you can use the first kind directly in an IsExpression. The first kind is really rather useless, as far as I know. Argubaly, the language would be nicer without it.
December 17
On Sunday, 17 December 2017 at 16:19:00 UTC, ag0aep6g wrote:
> On Sunday, 17 December 2017 at 14:44:15 UTC, Alexandru Ermicioi wrote:
>> Suppose:
>> --------
>> struct F {
>>     static void foo(T)(T i, int o) {}
>> }
>>
>> enum bool check(T) = is(F.foo!T == void function(Z, int), Z);
>>
>> enum correct = check!int;
>> --------
>>
>> Upon running it will return false, though, by logic is expression could deduce that F.foo is conformat to function signature in check test.
>
> Here, `F.foo!T` is the function itself, not its type. You forgot `typeof`.
>
>> It is interesting that it will not work with global functions as well:
>>
>> --------
>> void foo(int i, double d) {};
>> enum bool check = is(typeof(foo) == void function(int, double));
>> --------
>>
>> It will be as well evaluated to false.
>
> Write `typeof(&foo)` to make it work.
>
> There are two kinds of function types in D:
>
> 1) "Proper" function types, e.g. `typeof(foo)` which gets printed as "void(int i, double d)", and
> 2) function pointer types, e.g. `typeof(&foo)` which gets printed as "void function(int i, double d)".
>
> As you see, the second kind is the one you're comparing against. I don't think you can use the first kind directly in an IsExpression. The first kind is really rather useless, as far as I know. Argubaly, the language would be nicer without it.

Thanks for help, ag0aep6g and Ali.

Now it is more clear why it didn't work. Although I did try to use FunctionTypeOf, which failed, and it seems due to explanation about two kinds of function types. It seems that FunctionTypeOf returns first kind which does not work with is expression, and not second.
See the example (first line):

------------------
import std.traits;

struct T {
	static void coo(M)(M e, int i);
}

void main() {
	pragma(msg, is(FunctionTypeOf!(&T.coo!int) == void function(Z, int), Z));
	pragma(msg, is(FunctionTypeOf!(&T.coo!X) == void function(X, int), X));
	pragma(msg, is(typeof(&T.coo!int) == void function(Z, int), Z));
	pragma(msg, is(typeof(&T.coo!X) == void function(X, int), X));
}
------------------

If run, first line will return false (even without &).

The initial question was related actually to another thing that I've tried to do, which is pattern matching on templated functions. It failed, see line 2, and 4.

It seems that now it is impossible to do pattern matching on templates, only on instantiated types.
Is there any possibility to check the internals of a template without instantiating it?
It would be good for using Policy pattern where you want for example to test passed policy, has a templated function with a desired signature for it.