Using 'auto' for return types seems just awful to me. In the context of a collaborative project, I don't want to have to dig through the implementation of someone else's function just to figure out what type it returns. Having an explicit return type is a form of self-documenting code.
The primary use-case of auto returns is for templated functions where the return type depends on the thing passed in. For example, in C++11 you have to write things like the following:
The return type can't be specified by the function[0], and you have to copy and paste the body of the function into the decltype() clause to tell the compiler that the return type is whatever the thing it's wrapping returns. When you have some long and complicated expression rather than just r.begin() in the body, this duplication becomes a major issue.
[0] In this specific case you could require that Range have an iterator typedef and return that, but that approach does not generalize.
C++ templates used to be the most unreadable code this side of Perl, but with auto and a little documentation you can figure out what's happening fairly easily. Templates (and auto) are typically used when dealing with core libraries and should be documented better than average code anyway.
If someone starts using auto for every variable or returning it from every method, then they need a stern talking-to.
If there is a feature that could be misused, it will be misused.
It does not matter what the rationale behind the committee's decision was. This is standard practice in duck typed languages, and it will be adopted as well in C++, since it will be (imho, correctly) perceived as another step to bring C++ "to the 21th century".
You can stern-talk as much as you wish... but it won't have much effect unless backed up by an (effectively enforced) internal code style guide.
The barbarians are already at the gate. Which side are you going to pick?
> This is standard practice in duck typed languages
Only because there is no choice in those languages -- and, in those language communities, there's considerable call for finding a good way to include optional explicit and enforced declared typing specifically so that a choice does exist.
So, even given that communities that (unlike C++, even with auto existing) accept languages that don't provide an alternative to to the equivalent of "auto everywhere" push back against that practice to the extent of seeking language features to provide an alternative to it, I don't think that auto becoming an option is going to mean auto everywhere takes over C++.
There'll probably be some overuse (particularly in a brief period before a widely-accepted conventions on appropriate use are established), but its hardly the most dangerously abusable feature of the C/C++ language family.
If there is a feature that could be misused, it will be misused. It does not matter what the rationale behind the committee's decision was.
This is quite a narrow-minded line of thinking. You're saying "Feature X is should be excluded because of <possible consequence>". But we can say the converse about this same feature: "Feature Y should be included because <possible benefit>". Every programming language feature ever has had its pros and cons, and every language designer makes tradeoffs deciding which features to include and which to exclude.[1]
You also most likely overestimate the practical unreadability of the source code. IDEs are (or will be) smart enough to deduce and display the type of an auto declared variable[2] when you want it. For short functions, it will be blindingly obvious what the auto-declared return type of a function is. Using auto will vastly improve readability by reducing textual noise when a function returns (1) heavily templated expressions, (2) any type within a deeply-nested namespace, (3) any type with a long name, or especially (4) combinations of the previous three (e.g. std::vector::const_iterator< std::pair<std::string, double> >). Complicated types are a common issue in languages with static type systems[3].
I could go on. There are tons of use-cases where auto will help out. The biggest complaint I have is that you can auto-declare the return type of methods that return private variables from a class (unless I'm mistaken; I haven't actually tried it). This pokes leaky holes in your class's encapsulation, forming dependencies between external code and your class's private, internal implementation (although this may be possible through template magic...).
The barbarians are already at the gate. Which side are you going to pick?
Oh, cut the drama. Every language has some sort of a style guide, and C++ programmers are already used to following a style guide and programming with discipline. One more feature with a few downsides and a number of benefits is not going to make a difference, and is totally in line with its philosophy[1].
IDEs are (or will be) smart enough to deduce and display the type of an auto declared variable[2] when you want it.
Not to detract from your other points, but personally I wouldn't want to live in a world where my IDE is decided for me. A person sometimes has decades of experience with their text editor. Forcing them to use a different one just to do programming isn't necessarily the best idea.
Interesting question: Will the world benefit from a language that requires an IDE to program in? I can imagine how the answer might be "yes," but also other scenarios where it might be "no."
He has some good points, but his perspective seems to be biased by a professional focus on writing libraries and more general-purpose code. He's also brilliant and can remember things like this:
const int& cir = val;
auto h = cir;
//The type of h is int.
It's difficult to make generic rules for how to use C++ (because it's used for everything from adware to nuclear reactors), but I can say that Herb's AAA (Almost Always Auto) rule would not fly on any development team I've ever worked with.
The type of h isn't so hard to understand, there. |auto| gives you a value; if you want a reference, use |auto&|. This rule actually makes |auto| more readable: you always know if you're looking at a reference or not.
Probably you expected |auto| to behave like |decltype()|, C++11's other form of type deduction, which gives you the actual type of an expression. C++14 adds |decltype(auto)|, which lets you declare local variables using this behavior if you want it.
I'm not sure whether I'd apply Herb's AAA rule quite as broadly as he suggests, but I think it's broadly right, because far too often in C++ we write a type twice on the same line, which is just redundant. I vastly prefer |auto val = new MyClass;| to |MyClass val = new MyClass;|, and similarly |auto casted = static_cast<MyType>(uncasted);| is completely readable without typing writing "MyType" a second time. C++ programmers are a conservative lot, but I expect using |auto| at least in those cases to be pretty mainstream within a few years.
That's a reasonable position, but the popularity of languages without any type declarations at all suggests that there are many people who don't mind. (python, ruby, etc.)
Having the type be inferred is precisely what omitting a type declaration does in a static language. From the point of view of a pedantic type systems theorist, Python is like having a static language where every variable has the the same type, "Object".
Anyway, they are talking about documentation. Many people think that having to peek inside a function to know what it returns is worse than having a compiler-checked type declaration. In fact, in most languages with type inference there is still a strong convention to write full signatures for all top level functions, as a form of documentation (return type inference is left for lambdas)
I suspect that over time the C++ community will settle on a set of conventions around the use of auto in this context. Much like how passing in a mutable reference is considered a no-no and you're expected to instead pass in a mutable pointer so it's obvious to the caller that you can change the value via the parameter list.
That's not a C++ community convention, it's just another bone headed part of the Google C++ coding standards. It's stupid because now everything is potentially nullable and every single function will start with:
if (!arg1 || !arg2 || !arg3 ...) {
what_I_should_do_here_isnt_really_clear();
I'm not a fan of the "pointer means mutable" idiom either. I feel you should only use a raw pointer type instead of a reference if you want nullptr to be a meaningful value. Value semantics are great.
I'm not a fan of idealism for the sake of idealism. It's practical to be able to tell at the callsite that the parameter can be changed by the function/method.
I think in any sane library, public API functions will have declared return types. It's only for small helper functions inside a source file that will be autoed. I agree that misuse of auto is going to be terrible, though.
Same can be said about using 'auto' for variable type declarations. It all comes down to "use, but don't abuse" (as most things in C++) - it can improve readability, if used moderately; and it is up to the programmer to judge where to use it.
Note that this can be used for static functions, I don't think anyone would find it in an API documentation. The real reason I see for this is reducing voodoo in template libraries, eg forwarding a call T::something() for a generic type 'T'.
Interesting, could you elaborate on this a bit more?
Say I have a header file "foo.h" with an "auto foo();" declaration. Another file (eg, "bar.h") imports foo.h. How can the compiler do type checking when compiling bar.cc without also parsing foo.cc to determine the return type of foo()?
Type inference has been a fantastic blessing for me in C#, so I'll never complain about having to type locals... by extension, implicitly-typed privates seems to make sense. But the public interface of a class? That just feels one step too far.
What if it's a private interface, like a local function? Or a public interface with limited consumers? The language should allow you to write your code the way you want.
Requiring pointless verbosity on some hope that somehow that'll help bad programmers write better code seems like an odd conclusion.
Yeah, we'll end up with some type of Hungarian notation for function naming. A lot of 'Modern C++' seems to be taking over what is really the job of an IDE, just because the original C++ syntax was so verbose.
Of course, using such a function in an expression when
only a forward declaration has been seen is ill-formed:
auto f(); // return type is unknown
int i = f(); // error, return type of f is unknown
Sure, auto probably shouldn't be used on a function that's part of the exposed API of a library, rather than something internal to the unit of code it is part of.
Its kind of weird to see people complaining about a C++ feature because its not appropriate to use indiscriminately and requires some discipline -- that's historically been pretty much the whole of C/C++.
Agreed - the popularity of implicit typing is surprising to me. It seems to make code much less readable and comprehensible. In a good IDE I suppose it doesn't really matter because type information could be provided automatically, but code isn't always read in a good IDE.
Function name and context usually is sufficient to know what SomeIterator refers to, there is no need for horrible STL constructs to try to explain it.
Readability is about how quickly you can figure out what's going on. There are only a few bits of syntax you need to know what's going on in the first example, but it requires mentally matching together the angle brackets correctly, and it emphasises the type over the function name.
In most cases you can scan over the type ('map blah blah...iterator') but that's not reading and in any case will quickly fail you with nested template types, if you're unfortunate enough to have those.
Functions that return iterators are never called getSomeIterator(). Instead they're called stuff like erase(), insert(), or even nonsense words like crend().
And whether a function returns an iterator is not consistent even within the STL:
auto loc = container.find("name");
What type is loc? If container is a std::map, then loc is an iterator. If container is a std::string, then loc is a size_t.
If you had used the explicit iterator type, you would at least get an error message immediately with the above line, instead of hoping your code does something that size_t doesn't support.
In fact, with an IDE, this argument is moot. You can have the type anyway.
Then, we do use template parameters already, for which we usually don't know the type. I can't see why we'd bitch about 'auto' and not about the template parameters.
It's just the same thing: coding against interfaces and not implementations.
A key difference is that we are being told to use auto (but not templates) gratuitously, even when there's only one possible type.
I prefer to make functions ordinary, and only templatize functions that need to operate on more than one type. There's good reasons for this: the compiler is less effective at type-checking templates, they require the function body to be visible, and they may fail to warn you when passed the wrong type.
"auto" suffers from all those problems, and yet we are being told to use it whenever possible. That's bad advice.
Template is explicit; auto can sneak under your radar and look like things you already think you know how they work. Any change to the mainstream syntax can be troublesome at first.
Remember this is primarily for non-public facing or complex objects. If you are looking at someones API on github it should not be using auto for return types.