www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - template instantiation --- having trouble therewith

reply "Carl Sturtivant" <sturtivant gmail.com> writes:
template Dptr( T, U...) {
	alias T delegate( U args) Dptr;
}

Dptr!(T,U) muddle( T, U...)( Dptr!(T,U) f) {
	return f; //or make another delegate in real code
}


unittest {
	import std.stdio;
	int x = 3;
	int scale( int s) { return x * s; }
	Dptr!(int,int) f = muddle( &scale);
	writeln( f(7));
}
============================================

The above technique seemed natural to me, but I get this message 
from dmd:

p1.d(15): Error: template p1.muddle does not match any function 
template declaration. Candidates are:
p1.d(7):        p1.muddle(T, U...)(Dptr!(T, U) f)
p1.d(15): Error: template p1.muddle(T, U...)(Dptr!(T, U) f) 
cannot deduce template function from argument types !()(int 
delegate(int))

and if I use muddle!(int,int) instead it doesn't help. This is 
likely a misunderstanding on my part --- please show me how to 
sort this out.
Sep 02 2013
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 3 September 2013 at 03:49:52 UTC, Carl Sturtivant 
wrote:
 template Dptr( T, U...) {
 	alias T delegate( U args) Dptr;
 }

 Dptr!(T,U) muddle( T, U...)( Dptr!(T,U) f) {
 	return f; //or make another delegate in real code
 }


 unittest {
 	import std.stdio;
 	int x = 3;
 	int scale( int s) { return x * s; }
 	Dptr!(int,int) f = muddle( &scale);
 	writeln( f(7));
 }
 ============================================

 The above technique seemed natural to me, but I get this 
 message from dmd:

 p1.d(15): Error: template p1.muddle does not match any function 
 template declaration. Candidates are:
 p1.d(7):        p1.muddle(T, U...)(Dptr!(T, U) f)
 p1.d(15): Error: template p1.muddle(T, U...)(Dptr!(T, U) f) 
 cannot deduce template function from argument types !()(int 
 delegate(int))

 and if I use muddle!(int,int) instead it doesn't help. This is 
 likely a misunderstanding on my part --- please show me how to 
 sort this out.
I'm confused as to what you're trying to do... your example code is equivalent to import std.stdio; int x = 3; int scale( int s) { return x * s; } auto f = &scale; writeln( f(7) );
Sep 03 2013
parent reply "Carl Sturtivant" <sturtivant gmail.com> writes:
 I'm confused as to what you're trying to do... your example 
 code is equivalent to

   import std.stdio;
   int x = 3;
   int scale( int s) { return x * s; }
   auto f = &scale;
   writeln( f(7) );
No it isn't according to dmd. My code is a minimal piece that produces the same error as some real code. The higher order generic function muddle in the real code is supposed to transform one delegate into another, but I still get the template problem if muddle is the identity function (given here). My example code isn't equivalent to the above according to the compiler. Why is that? And how can I make it work?
Sep 03 2013
next sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Carl Sturtivant wrote:

 No it isn't according to dmd.
dmd does not express this. according to
 p1.d(15): Error: [...]
dmd "cannot deduce" that `Dptr!(T, U)' might be equal to `int delegate(int)' -manfred
Sep 03 2013
next sibling parent reply "Carl Sturtivant" <sturtivant gmail.com> writes:
On Tuesday, 3 September 2013 at 13:42:44 UTC, Manfred Nowak wrote:
 Carl Sturtivant wrote:

 No it isn't according to dmd.
dmd does not express this. according to
 p1.d(15): Error: [...]
dmd "cannot deduce" that `Dptr!(T, U)' might be equal to `int delegate(int)' -manfred
I understood that. How do I fix this? Writing muddle!(int,int) in the unit test so there's no type inference needed gives the same error message.
Sep 03 2013
next sibling parent Manfred Nowak <svv1999 hotmail.com> writes:
Carl Sturtivant wrote:
 How do I fix this?
maybe it is currently not fixable because of restrictions in the deduction algorithm. Obviously the deduction works if the instantion of the template is replaced by a symbol by `alias T delegate( U) Dptr;' or similar. -manfred
Sep 03 2013
prev sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Carl Sturtivant wrote:
 Writing muddle!(int,int)
[...]
 gives the same error message.
Not entirely true: template muddle( T, U...){ alias T delegate( U) Dptr; auto muddle1( T, U...)( Dptr f) { return f; //or make another delegate in real code } alias muddle1!( T, U) muddle; } unittest { import std.stdio; int x = 3; int scale( int s) { return x * s; } auto f= muddle!( int, int)( &scale); writeln( f(7)); } -manfred
Sep 03 2013
next sibling parent "Carl Sturtivant" <sturtivant gmail.com> writes:
On Tuesday, 3 September 2013 at 17:25:12 UTC, Manfred Nowak wrote:
 Carl Sturtivant wrote:
 Writing muddle!(int,int)
[...]
 gives the same error message.
Not entirely true: template muddle( T, U...){ alias T delegate( U) Dptr; auto muddle1( T, U...)( Dptr f) { return f; //or make another delegate in real code } alias muddle1!( T, U) muddle; } unittest { import std.stdio; int x = 3; int scale( int s) { return x * s; } auto f= muddle!( int, int)( &scale); writeln( f(7)); }
Can you point me at some documentation that explains this behavior?
Sep 04 2013
prev sibling parent "Carl Sturtivant" <sturtivant gmail.com> writes:
On Tuesday, 3 September 2013 at 17:25:12 UTC, Manfred Nowak wrote:
 Carl Sturtivant wrote:
 Writing muddle!(int,int)
[...]
 gives the same error message.
Not entirely true: template muddle( T, U...){ alias T delegate( U) Dptr; auto muddle1( T, U...)( Dptr f) { return f; //or make another delegate in real code } alias muddle1!( T, U) muddle; } unittest { import std.stdio; int x = 3; int scale( int s) { return x * s; } auto f= muddle!( int, int)( &scale); writeln( f(7)); } -manfred
This technique does what I want if there's a single parameter to the delegate. I'll explore from here; thanks for all the examples. Carl.
Sep 04 2013
prev sibling parent "Carl Sturtivant" <sturtivant gmail.com> writes:
On Tuesday, 3 September 2013 at 13:42:44 UTC, Manfred Nowak wrote:
 Carl Sturtivant wrote:

 No it isn't according to dmd.
dmd does not express this. according to
 p1.d(15): Error: [...]
dmd "cannot deduce" that `Dptr!(T, U)' might be equal to `int delegate(int)'
Indeed, dmd doesn't know the equivalence, and therefore won't compile my code.
Sep 04 2013
prev sibling next sibling parent reply Manfred Nowak <svv1999 hotmail.com> writes:
Carl Sturtivant wrote:
 is supposed to transform one delegate into another
Then please declare the template parameters to be delegates: U muddle( T, U)( T f) { uint g( int fp){ return cast(uint)( 5* f( fp)); } auto gP= &g; return gP; } unittest { import std.stdio; int x = 3; int scale( int s) { return x * s; } auto f= muddle!( int delegate( int), uint delegate( int))( &scale); writeln( f(7)); } // no deduction problems -manfred
Sep 03 2013
parent "Carl Sturtivant" <sturtivant gmail.com> writes:
On Tuesday, 3 September 2013 at 21:52:58 UTC, Manfred Nowak wrote:
 Carl Sturtivant wrote:
 is supposed to transform one delegate into another
Then please declare the template parameters to be delegates: U muddle( T, U)( T f) { uint g( int fp){ return cast(uint)( 5* f( fp)); } auto gP= &g; return gP; } unittest { import std.stdio; int x = 3; int scale( int s) { return x * s; } auto f= muddle!( int delegate( int), uint delegate( int))( &scale); writeln( f(7)); }
But I want some inference. In the real code the relevant delegates will have lots of long messy signatures that have already been declared. And in your example above, I want the arguments of the delegates in general to be a type tuple, because any delegate may be passed.
Sep 04 2013
prev sibling parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Tuesday, 3 September 2013 at 11:51:37 UTC, Carl Sturtivant 
wrote:
 I'm confused as to what you're trying to do... your example 
 code is equivalent to

  import std.stdio;
  int x = 3;
  int scale( int s) { return x * s; }
  auto f = &scale;
  writeln( f(7) );
No it isn't according to dmd. My code is a minimal piece that produces the same error as some real code. The higher order generic function muddle in the real code is supposed to transform one delegate into another, but I still get the template problem if muddle is the identity function (given here). My example code isn't equivalent to the above according to the compiler. Why is that? And how can I make it work?
Ok, that makes more sense. The reason why it doesn't work is that you're effectively asking the compiler to work backwards from {the type of the delegate passed to muddle} to {the type parameters that would have to be used in Dptr to generate that delegate type}. I'm no expert on type-deduction algorithms, but I seriously doubt that's a solvable problem in the general case, especially considering that the definition of Dptr could contain string mixins etc. In the general case, all code is forwards-only. Anyhow, it's easy to work around: import std.traits : ReturnType, ParameterTypeTuple; template Dptr( T, U...) { alias T delegate( U args) Dptr; } auto muddle( DT)( DT f) { alias T = ReturnType!f; alias U = ParameterTypeTuple!f; //use T and U return f; //or make another delegate in real code } unittest { import std.stdio; int x = 3; int scale( int s) { return x * s; } Dptr!(int,int) f = muddle( &scale); writeln( f(7)); }
Sep 05 2013
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 5 September 2013 at 09:00:27 UTC, John Colvin wrote:
 On Tuesday, 3 September 2013 at 11:51:37 UTC, Carl Sturtivant 
 wrote:
 I'm confused as to what you're trying to do... your example 
 code is equivalent to

 import std.stdio;
 int x = 3;
 int scale( int s) { return x * s; }
 auto f = &scale;
 writeln( f(7) );
No it isn't according to dmd. My code is a minimal piece that produces the same error as some real code. The higher order generic function muddle in the real code is supposed to transform one delegate into another, but I still get the template problem if muddle is the identity function (given here). My example code isn't equivalent to the above according to the compiler. Why is that? And how can I make it work?
Ok, that makes more sense. The reason why it doesn't work is that you're effectively asking the compiler to work backwards from {the type of the delegate passed to muddle} to {the type parameters that would have to be used in Dptr to generate that delegate type}. I'm no expert on type-deduction algorithms, but I seriously doubt that's a solvable problem in the general case, especially considering that the definition of Dptr could contain string mixins etc. In the general case, all code is forwards-only. Anyhow, it's easy to work around: import std.traits : ReturnType, ParameterTypeTuple; template Dptr( T, U...) { alias T delegate( U args) Dptr; } auto muddle( DT)( DT f) { alias T = ReturnType!f; alias U = ParameterTypeTuple!f; //use T and U return f; //or make another delegate in real code } unittest { import std.stdio; int x = 3; int scale( int s) { return x * s; } Dptr!(int,int) f = muddle( &scale); writeln( f(7)); }
Having said that, in the case where you explicitly set the template parameters to muddle I think it *should* work and is probably a bug (or at least a simple enhancement) that it doesn't.
Sep 05 2013
parent reply "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 5 September 2013 at 09:11:06 UTC, John Colvin wrote:
 On Thursday, 5 September 2013 at 09:00:27 UTC, John Colvin 
 wrote:
 On Tuesday, 3 September 2013 at 11:51:37 UTC, Carl Sturtivant 
 wrote:
 I'm confused as to what you're trying to do... your example 
 code is equivalent to

 import std.stdio;
 int x = 3;
 int scale( int s) { return x * s; }
 auto f = &scale;
 writeln( f(7) );
No it isn't according to dmd. My code is a minimal piece that produces the same error as some real code. The higher order generic function muddle in the real code is supposed to transform one delegate into another, but I still get the template problem if muddle is the identity function (given here). My example code isn't equivalent to the above according to the compiler. Why is that? And how can I make it work?
Ok, that makes more sense. The reason why it doesn't work is that you're effectively asking the compiler to work backwards from {the type of the delegate passed to muddle} to {the type parameters that would have to be used in Dptr to generate that delegate type}. I'm no expert on type-deduction algorithms, but I seriously doubt that's a solvable problem in the general case, especially considering that the definition of Dptr could contain string mixins etc. In the general case, all code is forwards-only. Anyhow, it's easy to work around: import std.traits : ReturnType, ParameterTypeTuple; template Dptr( T, U...) { alias T delegate( U args) Dptr; } auto muddle( DT)( DT f) { alias T = ReturnType!f; alias U = ParameterTypeTuple!f; //use T and U return f; //or make another delegate in real code } unittest { import std.stdio; int x = 3; int scale( int s) { return x * s; } Dptr!(int,int) f = muddle( &scale); writeln( f(7)); }
Having said that, in the case where you explicitly set the template parameters to muddle I think it *should* work and is probably a bug (or at least a simple enhancement) that it doesn't.
I filed a bug report for it http://d.puremagic.com/issues/show_bug.cgi?id=10969
Sep 05 2013
parent "John Colvin" <john.loughran.colvin gmail.com> writes:
On Thursday, 5 September 2013 at 09:33:00 UTC, John Colvin wrote:
 On Thursday, 5 September 2013 at 09:11:06 UTC, John Colvin 
 wrote:
 On Thursday, 5 September 2013 at 09:00:27 UTC, John Colvin 
 wrote:
 On Tuesday, 3 September 2013 at 11:51:37 UTC, Carl Sturtivant 
 wrote:
 I'm confused as to what you're trying to do... your example 
 code is equivalent to

 import std.stdio;
 int x = 3;
 int scale( int s) { return x * s; }
 auto f = &scale;
 writeln( f(7) );
No it isn't according to dmd. My code is a minimal piece that produces the same error as some real code. The higher order generic function muddle in the real code is supposed to transform one delegate into another, but I still get the template problem if muddle is the identity function (given here). My example code isn't equivalent to the above according to the compiler. Why is that? And how can I make it work?
Ok, that makes more sense. The reason why it doesn't work is that you're effectively asking the compiler to work backwards from {the type of the delegate passed to muddle} to {the type parameters that would have to be used in Dptr to generate that delegate type}. I'm no expert on type-deduction algorithms, but I seriously doubt that's a solvable problem in the general case, especially considering that the definition of Dptr could contain string mixins etc. In the general case, all code is forwards-only. Anyhow, it's easy to work around: import std.traits : ReturnType, ParameterTypeTuple; template Dptr( T, U...) { alias T delegate( U args) Dptr; } auto muddle( DT)( DT f) { alias T = ReturnType!f; alias U = ParameterTypeTuple!f; //use T and U return f; //or make another delegate in real code } unittest { import std.stdio; int x = 3; int scale( int s) { return x * s; } Dptr!(int,int) f = muddle( &scale); writeln( f(7)); }
Having said that, in the case where you explicitly set the template parameters to muddle I think it *should* work and is probably a bug (or at least a simple enhancement) that it doesn't.
I filed a bug report for it http://d.puremagic.com/issues/show_bug.cgi?id=10969
and only 26.5 mins after posting the bug, there's a pull request to fix it: https://github.com/D-Programming-Language/dmd/pull/2526 That's what I call service :p
Sep 05 2013