www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Return type inference

reply "Tobias Pankrath" <tobias pankrath.net> writes:
This does not work and I can see why.

---
auto foo(int x)
{
          if(x < 0)
              return foo(-x);
          return x;
}
----

DMD 2.059 says:
oopsc/compiler/test.d(7): Error: forward reference to foo
oopsc/compiler/test.d(14): Error: forward reference to foo

For the human reader it is easy to see that the return type of
foo should be int. Could the following rule be added to make dmd
see this, too?

 If there are multiple ReturnStatements, the types of them must 
 match exactly. If there are no ReturnStatements, the return 
 type is inferred to be void.
 <new>
 If the function is called recursively the type of the result of 
 this call is inferred in the same way. If the recursive call is 
 part of a return statement >  then this statement is not 
 considered for type inference. If all return statements are 
 discarded in this way, it is an error.

May 17 2012
next sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 5/17/12, Tobias Pankrath <tobias pankrath.net> wrote:
 snip

http://d.puremagic.com/issues/show_bug.cgi?id=7483
May 17 2012
prev sibling next sibling parent Dmitry Olshansky <dmitry.olsh gmail.com> writes:
On 17.05.2012 17:10, Tobias Pankrath wrote:
 This does not work and I can see why.

 ---
 auto foo(int x)
 {
 if(x < 0)
 return foo(-x);

Pluck in other condition then x < 0 and you may see it's not so easy. Basically compiler has to deduce that recursion stops and trace down to the bottom of it.
 return x;
 }
 ----

 DMD 2.059 says:
 oopsc/compiler/test.d(7): Error: forward reference to foo
 oopsc/compiler/test.d(14): Error: forward reference to foo

 For the human reader it is easy to see that the return type of
 foo should be int. Could the following rule be added to make dmd
 see this, too?

 If there are multiple ReturnStatements, the types of them must match
 exactly. If there are no ReturnStatements, the return type is inferred
 to be void.
 <new>
 If the function is called recursively the type of the result of this
 call is inferred in the same way. If the recursive call is part of a
 return statement > then this statement is not considered for type
 inference. If all return statements are discarded in this way, it is
 an error.


-- Dmitry Olshansky
May 17 2012
prev sibling next sibling parent "Peter Alexander" <peter.alexander.au gmail.com> writes:
On Thursday, 17 May 2012 at 13:10:20 UTC, Tobias Pankrath wrote:
 For the human reader it is easy to see that the return type of
 foo should be int. Could the following rule be added to make dmd
 see this, too?

 If the function is called recursively the type of the result of 
 this call is inferred in the same way. If the recursive call is 
 part of a return statement >  then this statement is not 
 considered for type inference. If all return statements are 
 discarded in this way, it is an error.

It's not that simple: -------------------------------- int bar(int x); real bar(real x); auto foo(int x) { if (x < 0) return bar(foo(x-1)); return 0; } -------------------------------- In order to determine the first return type, it needs to find out what overloaded 'bar' to call, which requires determining the first return type. If you ignore the first return statement and only consider the int then there could be problems. e.g. if above we had: real bar(int x); And we ignored the first return statement then the determined return type would be wrong (would infer int, but bar(foo(x-1)) would return real).
May 17 2012
prev sibling next sibling parent reply "Steven Schveighoffer" <schveiguy yahoo.com> writes:
On Thu, 17 May 2012 09:10:18 -0400, Tobias Pankrath <tobias pankrath.net>  
wrote:

 This does not work and I can see why.

 ---
 auto foo(int x)
 {
           if(x < 0)
               return foo(-x);
           return x;
 }
 ----

 DMD 2.059 says:
 oopsc/compiler/test.d(7): Error: forward reference to foo
 oopsc/compiler/test.d(14): Error: forward reference to foo

 For the human reader it is easy to see that the return type of
 foo should be int.

At this point, I think the human should intervene: int foo(int x) ... I would *hate* to have to read code like yours to try and understand it. -Steve
May 17 2012
parent =?UTF-8?B?QWxleCBSw7hubmUgUGV0ZXJzZW4=?= <xtzgzorex gmail.com> writes:
On 17-05-2012 16:22, Steven Schveighoffer wrote:
 On Thu, 17 May 2012 09:10:18 -0400, Tobias Pankrath
 <tobias pankrath.net> wrote:

 This does not work and I can see why.

 ---
 auto foo(int x)
 {
 if(x < 0)
 return foo(-x);
 return x;
 }
 ----

 DMD 2.059 says:
 oopsc/compiler/test.d(7): Error: forward reference to foo
 oopsc/compiler/test.d(14): Error: forward reference to foo

 For the human reader it is easy to see that the return type of
 foo should be int.

At this point, I think the human should intervene: int foo(int x) ... I would *hate* to have to read code like yours to try and understand it. -Steve

I have to agree. Sometimes auto can be over-used. Even in functional languages with H-M type inference, I tend to always make my functions have explicit signatures (unless they're supposed to be generic). It's just clearer to the person reading the code later on. -- - Alex
May 17 2012
prev sibling next sibling parent "bearophile" <bearophileHUGS lycos.com> writes:
Andrej Mitrovic:

 http://d.puremagic.com/issues/show_bug.cgi?id=7483

Probably related: http://d.puremagic.com/issues/show_bug.cgi?id=8111 Bye, bearophile
May 17 2012
prev sibling parent "Tobias Pankrath" <tobias pankrath.net> writes:
 In order to determine the first return type, it needs to find 
 out what overloaded 'bar' to call, which requires determining 
 the first return type.

I didn't think of overloaded functions. If we consider only direct recursion, it should still work?
May 17 2012