cannot deduce function from argument types issue.

2015-02-10 Thread ted via Digitalmars-d-learn
Hi!

I get the following compile error (linux, dmd2.066.1):
test.d(13): Error: template test.testFunc cannot deduce function from 
argument types !()(double[], double), candidates are:
test.d(3):test.testFunc(R)(R range, ElementType!R foo)


For the following test file:
import std.range: ElementType, isInputRange;

ElementType!R testFunc(R)( R range, ElementType!R foo)  // compiles with 
double foo
{
static assert( isInputRange!R );
ElementType!R retVal = foo*foo;
return retVal;  


   
}   


   



   
void main() 


   
{   


   
double[] values = [0.0, 3.0, -1.0, 5.0];


   
auto result = testFunc( values, 8.8 );  


   
}

And I'm not sure what I'm doing incorrectly. It compiles/works fine if I 
hardcode the type for foo.
Could someone enlighten me ?

regards,
ted


Re: cannot deduce function from argument types issue.

2015-02-10 Thread ted via Digitalmars-d-learn
Ali Çehreli wrote:

 On 02/10/2015 12:31 AM, ted wrote:
 
   ElementType!R testFunc(R)( R range, ElementType!R foo) // 
compiles
   with double foo
 
 If think it is a little too much to ask from the template system of D. A
 proper way of doing the same thing is to use a template constraint:
 
 ElementType!R testFunc(R, E)( R range, E foo)
  if (is (E : ElementType!R))
 
 Ali

thanks !


Re: cannot deduce function from argument types issue.

2015-02-10 Thread Ali Çehreli via Digitalmars-d-learn

On 02/10/2015 12:31 AM, ted wrote:

 ElementType!R testFunc(R)( R range, ElementType!R foo) // compiles with
 double foo

If think it is a little too much to ask from the template system of D. A 
proper way of doing the same thing is to use a template constraint:


ElementType!R testFunc(R, E)( R range, E foo)
if (is (E : ElementType!R))

Ali



Re: cannot deduce function from argument types issue.

2015-02-10 Thread bearophile via Digitalmars-d-learn

ted:


Could someone enlighten me ?


This works:


import std.range: ElementType, isInputRange;

ElementType!R testFunc(R, T)(R range, T foo)
if (is(ElementType!R == T)) {
   static assert(isInputRange!R);
   typeof(return) retVal = foo ^^ 2; // More DRY.
   return retVal;
}

void main() {
   auto values = [0.0, 3.0, -1.0, 5.0];
   auto result = testFunc(values, 8.8);
}


The D compiler seems unable to compute ElementType!R in the 
function signature. If I am right, then this seems worth an 
enhancement request.


Bye,
bearophile


Re: cannot deduce function from argument types issue.

2015-02-10 Thread bearophile via Digitalmars-d-learn

Ali Çehreli:

If think it is a little too much to ask from the template 
system of D.


I remember hitting a similar problem with code like this bar() 
function:



// OK
void foo(size_t N1, size_t N2)(int[N1] a, int[N2] b)
if (N2 == N1 ^^ 2) {}

// Not OK
void bar(size_t N)(int[N] a, int[N ^ 2] b) {}

void main() {
int[2] a = [1, 2];
int[4] b = [1, 2, 3, 4];
foo(a, b);
bar(a, b);
}


So perhaps my suggestion to file an enhancement request is not a 
good idea...


Bye,
bearophile


Re: cannot deduce function from argument types issue.

2015-02-10 Thread bearophile via Digitalmars-d-learn

void bar(size_t N)(int[N] a, int[N ^ 2] b) {}


I meant:

void bar(size_t N)(int[N] a, int[N ^^ 2] b) {}


Re: cannot deduce function from argument types issue.

2015-02-10 Thread ted via Digitalmars-d-learn
bearophile wrote:

 ted:
 
 Could someone enlighten me ?
 
 This works:
 
 
 import std.range: ElementType, isInputRange;
 
 ElementType!R testFunc(R, T)(R range, T foo)
 if (is(ElementType!R == T)) {
 static assert(isInputRange!R);
 typeof(return) retVal = foo ^^ 2; // More DRY.
 return retVal;
 }
 
 void main() {
 auto values = [0.0, 3.0, -1.0, 5.0];
 auto result = testFunc(values, 8.8);
 }
 
 
 The D compiler seems unable to compute ElementType!R in the
 function signature. If I am right, then this seems worth an
 enhancement request.
 
 Bye,
 bearophile

thanks !...

... where you say 'More DRY' above, are you referring to 
 - foo^^2 ( I just did foo*foo for the sake of the example), or
 - typeof(return) - a construct I am completely unfamiliar with and will 
now have to look up !

If it is 'typeof(return)' why would this be selected over ElementType!R ?? 
Is it more idiomatic ?


regards,
ted


Re: cannot deduce function from argument types issue.

2015-02-10 Thread ted via Digitalmars-d-learn
bearophile wrote:

 ted:
 
 ... where you say 'More DRY' above, are you referring to
 
 I was referring to both, but mostly to the typeof. It's more DRY
 (http://en.wikipedia.org/wiki/Don%27t_repeat_yourself ). You are
 stating only once the type of the return variable. This is less
 bug-prone.
 
 Bye,
 bearophile

Ha !
..more stuff to learn!

many thanks...
regards,
ted


Re: cannot deduce function from argument types issue.

2015-02-10 Thread bearophile via Digitalmars-d-learn

ted:


... where you say 'More DRY' above, are you referring to


I was referring to both, but mostly to the typeof. It's more DRY 
(http://en.wikipedia.org/wiki/Don%27t_repeat_yourself ). You are 
stating only once the type of the return variable. This is less 
bug-prone.


Bye,
bearophile


Re: cannot deduce function from argument types issue.

2015-02-10 Thread Ali Çehreli via Digitalmars-d-learn

On 02/10/2015 01:08 AM, bearophile wrote:

 // Not OK
 void bar(size_t N)(int[N] a, int[N ^^ 2] b) {}

 So perhaps my suggestion to file an enhancement request is not
 a good idea...

I am not sure. Although the template system already does pretty clever 
deductions, I think they are all based on hints given by the programmer. 
They work forward from the rules.


However, both in your example above and in ted's code, the compiler has 
to solve a problem similar to declarative programming languages to 
arrive at the intent. For example, it must apply sqrt to the second 
length to figure out N.


Admittedly, it is not apparent in the code above because the first 
parameter is already trivially N so the human reader thinks N comes 
from the first argument and it must also satisfy the second argument.


The following would ask the compiler to work backward from the argument:

void bar(size_t N)(int[N ^^ 2] b) {}

Take a value from the argument, take its square root and then use that 
value to figure out the instantiation value of this template.


Ali