7 ms·
As I just posted to his blog: How about instead you use proper names? "Results" is a terrible name. So is "i". That is why you can't understand that code. Your
by RogerL 11y ago
As I just posted to his blog:
How about instead you use proper names? "Results" is a terrible name. So is "i". That is why you can't understand that code. Your 'fix' is still unreadable - the struct is rarely near the for loop, so you are going to have to go searching anyway to figure out what the hell is going on.
This is completely readable, IMO:
for (auto employee : sorted_employees) {
StoreEmpoyeeInFoo(employee);
}
- deleted 11y ago[deleted]
- Skunkleton 11y agoThere is still no indication what "employee" is, or what will happen when it is passed to the "StoreEmpoyeeInFoo" function.
- theyoungestgun 11y agoAgreed - but this is why modern features should be paired with modern tools. A simple hover-over or click through in an IDE to show what the function signature looks like is pretty basic these days. Autocomplete on what that auto variable's API offers getting better and better as well.
- pasas 11y agoHow does autocomplete and tooltips help you when diffing/merging code? It doesn't. Relying on IDEs to give you insight into what should be obvious by just looking at the code show's that something's wrong IMO.
- theyoungestgun 11y agoI do not consider the API of a reasonably complex construct "obvious". That is often where IDEs shine for me - in java or any other language that can gather that info for me. It's scenarios where I don't have to go to cppreference.com, because the IDE is going to give me what I want directly. I used to really be anal on making every single line explicit: no shortcuts. But over time, especially with increasing my usage of templates, I've come to relax on these things and prefer to put my efforts in good variable names and trusting the compiler. I'm not saying you should use auto for basic types (especially ones that can be easily cast into each other - that shit gets dangerous). I am saying that auto is extremely powerful when working with most interesting APIs. The most recent example I have is a lot of things I end up doing with chrono.
- Aleman360 11y ago> How does autocomplete and tooltips help you when diffing/merging code? It doesn't. Sounds like there's an opportunity for better diff tools.
- dysfunction 11y agoThere really is... diff tools that point to the compiler (or a parse tree for dynamically-typed languages) could be so much smarter than what we have now.
- Skunkleton 11y agoFrom my perspective this is fundamentally flawed logic. Why would you want to depend on a tool when you don't have to? Why would I want to hover over all sorts of auto variables to figure out their type when I could just read it instead?
- theyoungestgun 11y ago"When I don't have to" If I'm not going to depend on the IDE to tell me what a deduced variable type is, you can bet your ass I'm going to want to depend on it for autocompleting some of the insanely long type names are: std::chrono::steady_clock::time_point gets old real quick - and so does stead_clock::time_point (if you want to include the namespace).
- mannykannot 11y agoSpeaking as someone who has done a lot of C++ work with nothing more than Emacs, I don't think there is any particular value or virtue in using only the sort of tools that were available in the 80s. The problem of finding out exactly what sort of thing you are dealing with did not start with auto (the elements of expressions have never been labeled with their type), and I think better tools are the way to the solution. C++ is actually a good language for this, as as little as possible is left to be decided at runtime. With regard to the hovering issue specifically, there can be a great deal of visual clutter from type names that is a hinderance to understanding most of the time; now you only have to see it when you need it. That is only the start, however; a decent IDE should, for example, make it easy to go from there to the declaration of the type, should you want to.
- wvenable 11y agoDoes it matter? Clearly it's right or it wouldn't compile.
- RogerL 11y agoOkay, if I replace auto, then you know that employee is of type "EmployeeRec". Happy? Of course not. That still tells you basically nothing. Surely it does not tell you what the store function does (I argue 'storeXXX' is generally a bad name, the point is to use a good name for functions, I just threw boilerplate there). Comments plus good names will tell you what is going on. Replacing 'auto' with 'std::vector<EmployeeRec>' for the most part, doesn't. I'm not being dogmatic. If having the type there is important, then of course use the type, not auto. But it seems that everyone who writes a rant about auto shows us code with no comments, and terrible, meaningless variable and function names. Get that part right, and then, if you are still puzzled, and the code isn't meant to be generic, sure, put the type in. Why not? Somehow I manage to write and read tons of dynamic code that has no types whatsoever. I agree, sometimes I would like a type there, and that is a perfect time to not use auto. But in general, we are trying to write code at a higher level. I mostly don't want to write, or think about for (std::my_vector<some_long_type> i = blah.begin(); Sometimes I do, and in those cases I'll write it that way.
- slavik81 11y agoYou mean for (typename std::my_vector<some_long_type>::const_iterator i = blah.begin();
- zzalpha 11y agoThe fundamental issue pointed out in the post is an interesting one. It all begins with the assumption that with a language like C++, you can reason about things like performance without a lot of weird surprises. Much of that reasoning begins with understanding the types involved. Of course, I would argue if you wanted to complain about this, you should begin by rejecting operator overloading, which IMO is far more dangerous in this regard than the auto keyword. At least with auto, there's a visual indicator that something "magical" is going on, and if you want to really know the return type, you navigate to the function or whatever to figure out what that type is. With operator overloads, code that looks totally innocuous can end up doing extremely surprising things.
- api 11y agoThere is another related dimension too: C++ is verbose for a reason and sometimes trying too hard to make a thing not what it is does harm. C++'s verbosity carries information that has value. Personally I tend to not even use typedef's as often as other programmers do. I do it for really verbose stuff at times but I prefer always seeing what a type actually is in most cases. I find that it actually makes code more readable, though it does make refactoring slightly more annoying.
- zzalpha 11y agoAgreed. It's absolutely true that in an object instantiation, declaring the type twice (in the variable declaration and again in the construction) is repetitive. And it's a flaw in all object-based algol-style programming languages, which is why the var keyword was introduced to C#, and the diamond operator (while a half-assed solution for only part of the problem) was added to Java. But that's just one narrow use case where I see this feature being worthwhile.
- Retra 11y agoOperator overloading would be fine if everybody had some standard for how to employ it sensibly. Unfortunately, the C++ standard library (over)uses it poorly all over the place, so it's really not setting an example of moderation.