Sacrificing precision for ease of use?

| 6 Comments

I'm probably jumping the gun a little here as I can't find Herb Sutter's slides that Matt Pietrek is referring to, but... Once again I find myself asking why is it actually useful to repurpose the auto keyword in C++...

The idea seems to be that rather than this:

foo::iterator i = myList.begin();

You can do this:
// Type of 'i is inferred from the assignment
auto i = myList.begin();

I really don't get what's with these "productivity" enhancements that allow people to think less whilst coding. Let's assume that I gain something whilst writing the code by using this new feature; and I'm not convinced that I would. Does someone whose job it is to maintain that code going to have the same gain? Let's consider the situation, you're looking at unfamiliar code and you come across this line:

auto i = myList.begin();

There's no indication of what myList is. There's no indication of what begin() returns. There's no indication of which version of begin() we're calling; is there a const version that returns something different to the non-const version? This code communicates less than the code that it replaces...

And, of course, this is actually quite a simplistic example. Let's say we have this function on a collection class:

const CMyObject *CMyCollection::GetObject(i) const;

So we might have a call site like this:
const CMyObject *pObj = myCollection.GetObject(i);

Which could, perhaps, become:
auto pObj = myCollection.GetObject(i);

But what we'd rather do is restrict what we use pObj for, so we decide to manipulate it via one of the interfaces that it implements instead...
const IObjBase *pObj = myCollection.GetObject(i);

How do we do that with this new fangled auto? I assume we don't?

C++ is a very expressive language; it allows you to be precise about what you want to do. What I'd like to know is what value this change has that makes up for the fact that the code is now potentially less precise and communicates considerably less? Perhaps the slides from talk will explain more... To me it just looks like the kind of thing that a lazy programmer writing a code generator would ask for...

6 Comments

One thing I've wished for is similar to auto, I guess: the ability to get nested type(def)s from a type *or* an instance name. The myList example is typical:

std::list< CAdapt< CComPtr< IVeryLongInterfaceName> > > myList;

Rather than doing:

std::list< CAdapt< CComPtr< IVeryLongInterfaceName> > >::iterator i = myList.begin();

I sometimes wish I could do:

myList::iterator i = myList.begin();

Of course, I can get half the way there by typedeffing my container type to something a little more readable, but I would still prefer to be able to extract type info from an instance.

- Kim

Ouch, the templates disappeared in the HTML...

Fixed the templates for you...

I tend to use typedefs so it's never really a problem for me.

The slides that Matt was talking about are now available here (you want TLN309); they're worth looking at.

I actually don't think I jumped the gun; the slides add very little to the auto change. There's one slide which poses the question; Why tediously tell the compiler what it already knows? To which my answer is, because you're not only communicating with the compiler.

The slide then presents a simple example that could be made simpler by a typedef and then points out that the change has already been voted into "ISO C++ 0x" (the next release of ISO C++) and that it is of "significant and broadly applicable convenience, esp. with generic programming" Hmm. I'm not sure I agree. Surely with generic programming you know the types that you're dealing with when you write the template and you don't usually even have the 'my hand hurts from typing too much' excuse since often template types are represented by single letters; so we're down to T::const_iterator vs auto and, again, this is nothing a typedef couldn't shorten if you really wanted to...

And then we get to what looks like the real reason ;) It helps with syntax in "Concur" (a concurrent C++ language) and with "Linq" (Microsoft's new hype focus). I was, possibly, quite near the mark with my 'lazy code generator' comment...

I'd have liked to hear Herb talking about this slide as I'm sure he added lots of value.

The rest of the slides are well worth looking at and I'm a little confused as to why this auto change was the thing that Matt thought was "coolest"; but then I'm fast coming to the conclusion that I don't generally care for stuff that the 'community' thinks is "cool"... Admittedly Matt says that this is the coolest thing "at first glance"... I, personally, think that the concurrent programming stuff is interesting and that the "for each" changes are a nicer piece of syntactic sugar that is more widely applicable and has less potential problems than the auto change. The lambda stuff is nice too.

In the context of STL iterators, `auto` makes sense, but really what is desired is the concepts around them... Probably best would be something like this:

for (forward_iterator i = vec. begin(); i != vec.end(); ++i) { ... }

Knowing the type of a container doesn't help a reader - knowing the iterator semantics does. Plus, IMHO, it is a pain to typedef all of your data structures, since oftentimes they *don't* have semantic meaning; the semantics are expressed in the variable name itself. Though it probably would have been much better if we could just do this (which would change the grammar, but not add any keywords):

for (vec::iterator i = vec. begin(); i != vec.end(); ++i) { ... }

Outside of the STL concept... I don't see much use for `auto`. I do see usefulness in `object::nested_type`.

PS your filter blocked my syntax again... Are the spammers using Standard C++ to promote their crap nowadays?

Tom,

I agree, the concept is important but I'd rather know the full type as, if named correctly, you have more information... But anyway, I can see how auto might be useful for generic code or for code generators but what I'd really like to see is for people to review these ideas with a bit of reality about them... If it was presented as a way to make code generators or generic code easier to write then great, but all too often it's the new one true way to make programming easier... Pah (old cynic that I am)...

I've hacked at the spam filter again. I get a log of things that cause failures, and when people complain I, er, look at it and remove the offending rule. The filter got a bit over zealous when I was fighting the spam with just the filter, before I added the captcha element to it... Now the filter is probably over cautious, but it's a pain to work out all the rules that are over eager and remove them....

Leave a comment