auto: useful, annoying or bad practice?

Chris wendlec at tcd.ie
Tue May 1 09:14:26 UTC 2018


On Monday, 30 April 2018 at 21:56:23 UTC, H. S. Teoh wrote:
> On Mon, Apr 30, 2018 at 09:31:48PM +0000, Giles Bathgate via 
> Digitalmars-d wrote: [...]
[...]
>
>
> T

On Monday, 30 April 2018 at 21:56:23 UTC, H. S. Teoh wrote:
[...]

Appart from the good points Teoh has made, imagine you would have 
to statically type in for loops:

foreach (i; items)
   writefln("%s", i);

And, yeah, chainig would indeed be a PIA:

auto items = myRange.filter!(a => a.length);

Most of the time you don't really care about the exact type, only 
at the end of the block (e.g. it should be `string[]`). And the 
compiler always tells you about the types, e.g. something like 
"cannot implicitly convert `words` of type MapResult to 
string[]". And then, _at the end_, you can use something like

items.array;

to get `string[]`.

I think the problem is not `auto`, the problem is thinking in old 
ways. If you think old-style Java where you declare loads of 
statically typed class variables at the beginning, then you're in 
trouble. But in order to use `auto`, you have to use a different 
approach.

Java:

String name;
String address;
int uiid;
...

String getName()
{
   return name;
}
[...]

In D, you are more likely to use home made structs / ranges / 
tuples as return types that all have the same properties, so auto 
makes more sense (incomplete code):

auto byUser(R)(R entries)
{
   struct User
   {
     private
     {
        R entries;
     }
     this(R entries)
     {
       this.entries = entries;
     }

     @property bool empty() { return range empty? (true|false) }

     @property void popFront()
     {
       // e.g.
       entries = entries[1..$];
     }

     @property auto front()
     {
       return whatever;  // e.g. struct UserInfo { string name; 
size_t uuid; }
     }
   }
   return User(entries);
}

The struct `User` can perform whatever is necessary, it can be 
changed, even renamed but the return type will always conform to 
the range interface: empty, popFront, front, so the caller can be 
sure s/he can use it as a range. Also, the type of `entries` can 
change, but the code will still work. No need to redefine all the 
variables as a different type. Now

auto users = entries.byUser();

can be whatever and you can perform other range based algorithms 
[1]

auto herberts = entries.byUser.filter!(a => a.name == 
'Herbert')...etc.etc.

Imagine having to use handwritten static typing for that!

[1] https://tour.dlang.org/tour/en/gems/range-algorithms


More information about the Digitalmars-d mailing list