digitalmars.D.learn - template instantiation --- having trouble therewith
- Carl Sturtivant (25/25) Sep 02 2013 template Dptr( T, U...) {
- John Colvin (9/34) Sep 03 2013 I'm confused as to what you're trying to do... your example code
- Carl Sturtivant (8/15) Sep 03 2013 No it isn't according to dmd.
- Manfred Nowak (6/8) Sep 03 2013 dmd does not express this.
- Carl Sturtivant (4/12) Sep 03 2013 I understood that. How do I fix this? Writing muddle!(int,int) in
- Manfred Nowak (6/7) Sep 03 2013 maybe it is currently not fixable because of restrictions in the deducti...
- Manfred Nowak (18/20) Sep 03 2013 Not entirely true:
- Carl Sturtivant (3/22) Sep 04 2013 Can you point me at some documentation that explains this
- Carl Sturtivant (4/24) Sep 04 2013 This technique does what I want if there's a single parameter to
- Carl Sturtivant (3/10) Sep 04 2013 Indeed, dmd doesn't know the equivalence, and therefore won't
- Manfred Nowak (18/19) Sep 03 2013 Then please declare the template parameters to be delegates:
- Carl Sturtivant (6/24) Sep 04 2013 But I want some inference. In the real code the relevant
- John Colvin (29/46) Sep 05 2013 Ok, that makes more sense.
- John Colvin (4/53) Sep 05 2013 Having said that, in the case where you explicitly set the
- John Colvin (3/67) Sep 05 2013 I filed a bug report for it
- John Colvin (4/73) Sep 05 2013 and only 26.5 mins after posting the bug, there's a pull request
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
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
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
Carl Sturtivant wrote:No it isn't according to dmd.dmd does not express this. according top1.d(15): Error: [...]dmd "cannot deduce" that `Dptr!(T, U)' might be equal to `int delegate(int)' -manfred
Sep 03 2013
On Tuesday, 3 September 2013 at 13:42:44 UTC, Manfred Nowak wrote:Carl Sturtivant wrote: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.No it isn't according to dmd.dmd does not express this. according top1.d(15): Error: [...]dmd "cannot deduce" that `Dptr!(T, U)' might be equal to `int delegate(int)' -manfred
Sep 03 2013
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
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
On Tuesday, 3 September 2013 at 17:25:12 UTC, Manfred Nowak wrote:Carl Sturtivant wrote:Can you point me at some documentation that explains this behavior?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)); }
Sep 04 2013
On Tuesday, 3 September 2013 at 17:25:12 UTC, Manfred Nowak wrote:Carl Sturtivant wrote: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.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 04 2013
On Tuesday, 3 September 2013 at 13:42:44 UTC, Manfred Nowak wrote:Carl Sturtivant wrote:Indeed, dmd doesn't know the equivalence, and therefore won't compile my code.No it isn't according to dmd.dmd does not express this. according top1.d(15): Error: [...]dmd "cannot deduce" that `Dptr!(T, U)' might be equal to `int delegate(int)'
Sep 04 2013
Carl Sturtivant wrote:is supposed to transform one delegate into anotherThen 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
On Tuesday, 3 September 2013 at 21:52:58 UTC, Manfred Nowak wrote:Carl Sturtivant wrote: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.is supposed to transform one delegate into anotherThen 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)); }
Sep 04 2013
On Tuesday, 3 September 2013 at 11:51:37 UTC, Carl Sturtivant wrote: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)); }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 05 2013
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: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.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)); }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 05 2013
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:I filed a bug report for it http://d.puremagic.com/issues/show_bug.cgi?id=10969On Tuesday, 3 September 2013 at 11:51:37 UTC, Carl Sturtivant wrote: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.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)); }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 05 2013
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: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 :pOn Thursday, 5 September 2013 at 09:00:27 UTC, John Colvin wrote:I filed a bug report for it http://d.puremagic.com/issues/show_bug.cgi?id=10969On Tuesday, 3 September 2013 at 11:51:37 UTC, Carl Sturtivant wrote: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.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)); }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 05 2013