Re: template parameter inference and introspection

2017-02-24 Thread Meta via Digitalmars-d-learn

On Friday, 24 February 2017 at 11:17:46 UTC, John Colvin wrote:
Unfortunately that only works by accident of my example. A 
counterexample:


T foo(Q = float, T = short)(T t) { return t; }

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
import std.meta;

alias getInstantiation = f!(staticMap!(Typeof, T));
}

static assert(is(typeof(foo(3)) == int)); // ok
static assert(is(typeof(getInstantiation!(foo, 3)(3)) == int)); 
// fails


This looks like VRP is kicking in when it shouldn't, or maybe 
it's a different bug. 3 should be typed as int by default unless 
we explicitly ask for something else.


Re: template parameter inference and introspection

2017-02-24 Thread John Colvin via Digitalmars-d-learn

On Friday, 24 February 2017 at 14:06:22 UTC, Meta wrote:

On Friday, 24 February 2017 at 11:17:46 UTC, John Colvin wrote:
Unfortunately that only works by accident of my example. A 
counterexample:


T foo(Q = float, T = short)(T t) { return t; }

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
import std.meta;

alias getInstantiation = f!(staticMap!(Typeof, T));
}

static assert(is(typeof(foo(3)) == int)); // ok
static assert(is(typeof(getInstantiation!(foo, 3)(3)) == 
int)); // fails


This looks like VRP is kicking in when it shouldn't, or maybe 
it's a different bug. 3 should be typed as int by default 
unless we explicitly ask for something else.


VRP propagation is what makes the call possible, but that's a 
distraction. The problem is that getInstantiation is setting Q to 
int and leaving T to be it's default type of short, which is not 
the same as if you just call with an int (which infers T from t 
and leaves Q as it's default float. Fundamentally, you can't 
assume the same order of runtime and template arguments.


Re: template parameter inference and introspection

2017-02-24 Thread John Colvin via Digitalmars-d-learn

On Thursday, 23 February 2017 at 18:33:33 UTC, Meta wrote:

On Thursday, 23 February 2017 at 18:21:51 UTC, Meta wrote:
On Thursday, 23 February 2017 at 16:01:44 UTC, John Colvin 
wrote:
Is there any way to get a reference/alias to the 
instantiation of a template function that would be called, 
given certain parameters? I.e. to get the result of whatever 
template parameter inference (and overload resolution) has 
occurred?


E.g. for some arbitrarily complex foo:

static assert(__traits(compiles, foo(3)));
alias fooWithInt = someMagic(foo(3));

so if foo was `void foo(T)(T t) {}` then `fooWithInt` would 
be `foo!int`, but if it was `void foo(Q = float, T = long)(T 
t)` then `fooWithInt` would be `foo!(float, int)`


I don't believe so, because foo(3) is a value (void), not a 
type like foo!int would be. You can't get it back after you've 
called the function. You would have to do something like:


alias fooWithInt = someMagic!foo(3);

Where someMagic constructs the alias to foo!int based on the 
type of arguments passed, or something like that.


A quick and rough example I threw together. Annoyingly, I can't 
figure out a way to tell the compiler that I want to printout 
the symbol of fooWithInt, not call it without parens. The best 
I can do is print out its type.


void foo(T)(T t) {}
void foo(Q = float, T = long)(T t) {}

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
import std.meta;

alias getInstantiation = f!(staticMap!(Typeof, T));
}

alias fooWithInt = getInstantiation!(foo, 3);
alias fooWithLong = getInstantiation!(foo, 3L);

void main()
{
pragma(msg, typeof(fooWithInt));
pragma(msg, typeof(fooWithLong));
}


Unfortunately that only works by accident of my example. A 
counterexample:


T foo(Q = float, T = short)(T t) { return t; }

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
import std.meta;

alias getInstantiation = f!(staticMap!(Typeof, T));
}

static assert(is(typeof(foo(3)) == int)); // ok
static assert(is(typeof(getInstantiation!(foo, 3)(3)) == int)); 
// fails




Re: template parameter inference and introspection

2017-02-23 Thread Meta via Digitalmars-d-learn

On Thursday, 23 February 2017 at 18:21:51 UTC, Meta wrote:
On Thursday, 23 February 2017 at 16:01:44 UTC, John Colvin 
wrote:
Is there any way to get a reference/alias to the instantiation 
of a template function that would be called, given certain 
parameters? I.e. to get the result of whatever template 
parameter inference (and overload resolution) has occurred?


E.g. for some arbitrarily complex foo:

static assert(__traits(compiles, foo(3)));
alias fooWithInt = someMagic(foo(3));

so if foo was `void foo(T)(T t) {}` then `fooWithInt` would be 
`foo!int`, but if it was `void foo(Q = float, T = long)(T t)` 
then `fooWithInt` would be `foo!(float, int)`


I don't believe so, because foo(3) is a value (void), not a 
type like foo!int would be. You can't get it back after you've 
called the function. You would have to do something like:


alias fooWithInt = someMagic!foo(3);

Where someMagic constructs the alias to foo!int based on the 
type of arguments passed, or something like that.


A quick and rough example I threw together. Annoyingly, I can't 
figure out a way to tell the compiler that I want to printout the 
symbol of fooWithInt, not call it without parens. The best I can 
do is print out its type.


void foo(T)(T t) {}
void foo(Q = float, T = long)(T t) {}

alias Typeof(alias v) = typeof(v);

template getInstantiation(alias f, T...)
{
import std.meta;

alias getInstantiation = f!(staticMap!(Typeof, T));
}

alias fooWithInt = getInstantiation!(foo, 3);
alias fooWithLong = getInstantiation!(foo, 3L);

void main()
{
pragma(msg, typeof(fooWithInt));
pragma(msg, typeof(fooWithLong));
}


Re: template parameter inference and introspection

2017-02-23 Thread Meta via Digitalmars-d-learn

On Thursday, 23 February 2017 at 16:01:44 UTC, John Colvin wrote:
Is there any way to get a reference/alias to the instantiation 
of a template function that would be called, given certain 
parameters? I.e. to get the result of whatever template 
parameter inference (and overload resolution) has occurred?


E.g. for some arbitrarily complex foo:

static assert(__traits(compiles, foo(3)));
alias fooWithInt = someMagic(foo(3));

so if foo was `void foo(T)(T t) {}` then `fooWithInt` would be 
`foo!int`, but if it was `void foo(Q = float, T = long)(T t)` 
then `fooWithInt` would be `foo!(float, int)`


I don't believe so, because foo(3) is a value (void), not a type 
like foo!int would be. You can't get it back after you've called 
the function. You would have to do something like:


alias fooWithInt = someMagic!foo(3);

Where someMagic constructs the alias to foo!int based on the type 
of arguments passed, or something like that.


template parameter inference and introspection

2017-02-23 Thread John Colvin via Digitalmars-d-learn
Is there any way to get a reference/alias to the instantiation of 
a template function that would be called, given certain 
parameters? I.e. to get the result of whatever template parameter 
inference (and overload resolution) has occurred?


E.g. for some arbitrarily complex foo:

static assert(__traits(compiles, foo(3)));
alias fooWithInt = someMagic(foo(3));

so if foo was `void foo(T)(T t) {}` then `fooWithInt` would be 
`foo!int`, but if it was `void foo(Q = float, T = long)(T t)` 
then `fooWithInt` would be `foo!(float, int)`