Re: template instantiation --- having trouble therewith
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)); }
Re: template instantiation --- having trouble therewith
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.
Re: template instantiation --- having trouble therewith
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
Re: template instantiation --- having trouble therewith
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
Re: template instantiation --- having trouble therewith
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?
Re: template instantiation --- having trouble therewith
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.
Re: template instantiation --- having trouble therewith
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.
Re: template instantiation --- having trouble therewith
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.
Re: template instantiation --- having trouble therewith
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) );
Re: template instantiation --- having trouble therewith
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?
Re: template instantiation --- having trouble therewith
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
Re: template instantiation --- having trouble therewith
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
Re: template instantiation --- having trouble therewith
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.
Re: template instantiation --- having trouble therewith
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
Re: template instantiation --- having trouble therewith
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