View mode: basic / threaded / horizontal-split · Log in · Help
June 16, 2012
Using consistently auto as function return type
Do you consider it to be good or bad style of programming to use 
consistently auto as function return type?

One of the pros is that it saves some redundant typing when the 
function returns some complex templated type:

auto getValue()
{
    return MyType!(int, "asdf", 64).init;
}

But one of the cons is that you don't see what the function 
returns just by looking at the signature.

Are there some more severe issues that I'm missing?
June 16, 2012
Re: Using consistently auto as function return type
On Saturday, 16 June 2012 at 09:31:35 UTC, Tommi wrote:
> Do you consider it to be good or bad style of programming to 
> use consistently auto as function return type?
>
> One of the pros is that it saves some redundant typing when the 
> function returns some complex templated type:
>
> auto getValue()
> {
>     return MyType!(int, "asdf", 64).init;
> }
>
> But one of the cons is that you don't see what the function 
> returns just by looking at the signature.
>
> Are there some more severe issues that I'm missing?

 I've wondered a bit of this myself. I tend to have all my 
function return types explicit and tend to use auto more for 
values returned when I am going to be using them right away, or 
they vary slightly on type (but not function).

 Being as D is not C++ (with it's template system), it can still 
parse and make sense of a majority of the code but lacking a 
specific return type... I want to say it's a potential pitfall 
and trap for later. If it only returns a basic type then the 
problem isn't as severe since implicit casting can take place to 
fix minor variations of type (real/double, int/long, etc).

 Perhaps a suggestion on use, where auto should be used: As a 
lambda return type, or functions that return simple base types?  
Not to say it would prevent you from from using auto, but then 
the potential damage is lessened. Perhaps a bigger problem is 
that auto would hide type changes and potential problems because 
it was auto, but regarding templates with that I don't know. 
Mmmm... I need more experience.
June 16, 2012
Re: Using consistently auto as function return type
On 06/16/2012 11:31 AM, Tommi wrote:
> Do you consider it to be good or bad style of programming to use
> consistently auto as function return type?
>
> One of the pros is that it saves some redundant typing when the function
> returns some complex templated type:
>
> auto getValue()
> {
>      return MyType!(int, "asdf", 64).init;
> }
>
> But one of the cons is that you don't see what the function returns just
> by looking at the signature.
>
> Are there some more severe issues that I'm missing?

auto return types make functions semantically dependent on each other,
eg. the following is illegal code:

auto foo(){bar(); return 0; }
auto bar(){foo(); return 1; }

In order to resolve the return type of foo, the body of foo needs to be
analyzed, which involves resolving the return type of bar, therefore
the body of bar needs to be analyzed, which involves resolving the
return type of foo, therefore the body of foo needs to be analyzed, ...


The current implementation is very conservative, and rejects every
dependency cycle of auto return functions, even if the return types
could be resolved in theory.


Other than that, there are no more severe issues, I see these major
applications for auto return types:

- The body is very short and spells out the type explicitly, auto saves 
redundancy.

- The implementer does not know the exact return type himself, because
  it depends on template arguments.

- The user of the function does not need to know the return type. eg if
  it is a type local to the function.
June 16, 2012
Re: Using consistently auto as function return type
Tommi:

> Do you consider it to be good or bad style of programming to 
> use consistently auto as function return type?

In Python programming you don't specify the types of function 
arguments and return values, but while this is possible in 
Haskell too, it's good practice to write down input and output 
types for functions, and let the type inferencer work just inside 
functions.

In D I use auto often inside function, unless I want to change a 
type or unless I want to be sure a certain variable has a desired 
type. But for clarity/readability I prefer to specify 
input/output types of D functions, unless they return a complex 
range. In this case I sometimes add a static assert to be sure it 
yields a range of my desired type:

auto foo(...)
out (result) {
    static assert(ForeachType!(typeof(result)) == ushort);
}
body {
...
}


Bye,
bearophile
Top | Discussion index | About this forum | D home