Re: template instantiation --- having trouble therewith

2013-09-05 Thread John Colvin
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

2013-09-05 Thread John Colvin

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

2013-09-05 Thread John Colvin

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

2013-09-05 Thread John Colvin

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

2013-09-04 Thread Carl Sturtivant

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

2013-09-04 Thread Carl Sturtivant

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

2013-09-04 Thread Carl Sturtivant

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

2013-09-04 Thread Carl Sturtivant

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

2013-09-03 Thread John Colvin
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

2013-09-03 Thread Carl Sturtivant


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

2013-09-03 Thread Manfred Nowak
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

2013-09-03 Thread Manfred Nowak
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

2013-09-03 Thread Carl Sturtivant

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

2013-09-03 Thread Manfred Nowak
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

2013-09-03 Thread Manfred Nowak
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