This is ridiculous. C++ lambdas (and std::function) don't replace iterators except for the most fervent disciples of the Church of Haskell. They replace single-function interfaces in cases where you would have had to put together a custom struct that did exactly the same thing as a lambda with capture but in about 15 more lines.
An empirical study on the impact of C++ lambdas and programmer experience
81–90 of 112 posts
Re: An empirical study on the impact of C++ lambdas and programmer experience
#82The only true conclusion of this study is that students find C++ a bit intimidating. Which is not surprising at all, because C++ is a very complicated language ! It takes years , even decades before you can master this language - even then you probably won't be using all of its features. Back in the day, it took me a long time before I could truly grasp the C strings and pointers in general. Yes, I could write code w…
Yes C++ is complicated and yes students struggle with programming. It takes years to understand how to put a decent program together (separation of data, logic and transport etc). As for your guesswork with C-style strings, you should have been using std::string and using copy constructors to pass work into a thread (eg. who owns the data the thread is working on?). With modern things you can move the data into the t…
Standard library was, for one reason or another, unpopular back then. Or maybe because of the C Windows API and later MFC, which came with its own CString class...
Re: An empirical study on the impact of C++ lambdas and programmer experience
#83Lambdas are an incredibly useful construct, and, once you master them, they do make a lot of programming tasks much easier. However, C++ lambdas picked the most horrifically ugly syntax possible, and they switch between three subtly different semantics (copy, reference, move) depending on a single glyph. I feel bad for the people working on modern C++ - maintaining backwards compatibility is a huge constraint upon de…
C++14 improves upon lambda captures a lot. I'm also not aware of a move capture, only "by reference" (&) and "copy" (=). In C++14 you're allowed to put arbitrary assignments into the capture, e.g. [foo=std::move(bar)]() {}
It was ugly as heck and was removed as soon as I have c++14
Re: An empirical study on the impact of C++ lambdas and programmer experience
#84Earlier quoted context omitted.
Yeah - from what I can see, neither interface looks like idiomatic C++. EDIT: Looks like you beat me to the punch on some of these ;) Instead of: float getSum(marketBasket mb) { float retVal = 0; // Implement solution here // --------- marketBasket::iterator iter = mb.begin(); while (iter.hasNext()) { retVal += iter.get().price; iter.next(); } // --------- return retVal; } I'd rather see real SC++L compatible iterato…
"Idiomatic" doesn't necessarily mean better. I think objectively it's hard to argue that "item != market.end()" is superior to "iter.hasNext()". The latter accurately reflects the programmer's intent, while the former specifies an unnecessarily specific (and poor) implementation of the intent. First of all, using something like "market.cend() != const_iter" instead is arguably better practice (imagine you unintention…
At this point, I find the former much more readable than the latter.
I have seen the former a thousand times. I have seen the latter once - here, and here alone. Oh sure, I've seen similar patterns - under different names, usually under different languages - but I'm pretty sure this is exactly the first time I've ever seen it named "hasNext".
The worst bit is mixing SC++L terms - "::iterator" - and foreign idioms that do NOT conform to the SC++L concept of what I expect an "::iterator" to do. It is surprise and confusion of the worst kind. Even relatively inexperienced C++ programmers that I know would pause as I did, and ask - "Wait, what the fuck?", and then waste the next few minutes rediscovering what the hell the code is doing (absolutely nothing special that would call for special divergence from the norm.)
As such I must thoroughly disagree on the strength of the communication of intent between the two samples. The former might as well be plain English to me - the latter might as well be pig latin. Oh sure, I can figure it out - but it'll take me a minute. It DID take me a minute.
You want to steal patterns from Java or C#? Then at least name them after the Java or C# concept. Call it enumerator. Embrace the fact that you're using Java or C#'s idioms. Decry C++'s idioms as poor choices by the C++ language if you must. And hell, yes, there are exceptional cases where you can say "let's go with none of the above - the best solution is unconventional and unusual, using the normal idioms of no language."
You have very much failed to convince me that this is one of them.
And while you could perhaps argue that C#'s idioms are superior, I would note that you're a few decades late to the party on that count, and talking to the wrong guy. I wouldn't even disagree, necessarily. But C++'s idioms have a useful inertia at this point, and are frankly not that bad. Rather reasonable, even. Although they do have a learning curve.
> First of all, using something like "market.cend() != const_iter" instead is arguably better practice (imagine you unintentionally omit the "!").
I prefer to have a warning-as-error for the unparenthesized assignment you posit (if only because my coworkers probably didn't use yoda conditionals on the existing codebase). But hell, even yoda conditionals would be better.
> But programmers shouldn't need to consider whether the iterator is const or not when they just want to know if the loop is done.
Realistically, I won't - instead preferring auto, or never naming my iterators at all, as I've done in the std::accumulate example - as begin is overloaded appropriately.
> Also, consider the case where the vector is being modified (items inserted or deleted) inside the loop. It might be problematic either way, but "item != market.end()" is particularly bad in that situation.
Oh, I know what I want in this case! Iterator debugging to catch the problem. The PDF has the source code to ::hasNext:
bool marketBasket::iterator::hasNext() { return owner−>items.size() − index > 0; }
Do you see iterator debugging? I don't. What happens when index is greater than .size() because of a removed element?Based on other code, we know items is a std::vector. And thus that .size() is unsigned. And thus that the result of ...size() - index is unsigned. And thus that the result will underflow to a huge number, and that ::hasNext() will return true, leading to a buffer overflow.
If "item != market.end()" is particularly bad, then "iter.hasNext()" must be particularly downright evil, for it's doing even worse.
Note that any fix applied to ::hasNext could equally be applied to comparing against .end().
Re: An empirical study on the impact of C++ lambdas and programmer experience
#85Earlier quoted context omitted.
> there is a difference between using C in crazy ways As per my sibling, write me something as straightforward as a C++ RAII-using dtor in C without "using C in crazy ways". I will not hold my breath. The cost of a very minimal subset of C++ is literally zero , and yet significantly improves the likelihood of your code actually working. You're picking social baggage in either case: either understanding the subset of…
Yes, RAII and exceptions (as well as a few other things like being able to declare variables anywhere) is the reason why I liked C++ in 2000 more than C. But beyond that, it all went downhill. There was no reason to make C++ the most bloated language ever. The same is true of Javascript etc. Newbies will not be able to start, now, because they will think about let/var/const the same way as in C++ they have to think a…
Re: An empirical study on the impact of C++ lambdas and programmer experience
#86Earlier quoted context omitted.
> But programmers shouldn't need to consider whether the iterator is const or not when they just want to know if the loop is done. and they don't: http://en.cppreference.com/w/cpp/container/vector/end - there's an overload returning a const_iterator. You don't need to use 'cend'. And since insertion and deletion potentially invalidate iterators, 'hasNext()' is just as bad.
Yeah, maybe I didn't think the const thing through. I guess I was thinking that the benefit of using cend() is the double-check to make sure the iterator was declared as a const_iterator (when appropriate). But using "hasNext()", just like using "end()", you would lose the double-check. Perhaps I could instead claim that "item != market.end()" redundantly specifies the vector, "market", and thus presents an unnecessa…
The safest option is to compile this code as Rust and have it fail to satisfy the borrow checker. And basic syntax parsing because this is C++ - but ehh, details.
Certain static analysis tools may also catch the issue. Well, if you're using real C++ iterators and not ::hasNext at least.
Re: An empirical study on the impact of C++ lambdas and programmer experience
#87Earlier quoted context omitted.
"Idiomatic" doesn't necessarily mean better. I think objectively it's hard to argue that "item != market.end()" is superior to "iter.hasNext()". The latter accurately reflects the programmer's intent, while the former specifies an unnecessarily specific (and poor) implementation of the intent. First of all, using something like "market.cend() != const_iter" instead is arguably better practice (imagine you unintention…
> I think objectively it's hard to argue that "item != market.end()" is superior to "iter.hasNext()" Until you realize the purpose of the weird syntax in the former. Namely: you can write algorithms where an iterator is a drop-in replacement for a simple loop through all items in an array via pointer arithmetic, if you write it to take a start and an end iterator as templates. Plus said algorithm can take sub-ranges…
Re: An empirical study on the impact of C++ lambdas and programmer experience
#88Some people feel comfortable expressing things in a more traditional way, in part, because you cannot change the habits built over the course of decades by just announcing a new standard. After the standard including lambdas came out, compilers did not immediately comply to it, and it took some time for them to catch up. Then it took even more time for tutorials and books to catch up. And it will take time for the C+…
Compilers (at least clang, MSVC and GCC) released versions supporting lambdas well before the C++11 standard was finalized.
Re: An empirical study on the impact of C++ lambdas and programmer experience
#89Earlier quoted context omitted.
Unfortunately most teachers aren't like Kate Gregory, and I fully agree with her, they should stop teaching C -> C++. Already in 1994 it was obvious to me that it leads to bad unsafe code and worse, the mentality to micro-benchmark each code line.
I see that mentality in every language, even if its worse in C++ because "close to metal" and "we know C++, therefore we must be good programmers". What usually happens is that the code gets unreadable/unmaintainable quickly and is still a complete unoptimized mess at the macro level. Once you realize this you don't need C++ for most application domains. And for the domains where C++ matters you also realize you'd be…
And even though it was one of the languages I enjoyed most using after Turbo Pascal and I even gave C++ classes at the university, I am a firm believer that if Java, VB.NET and C# had been fully AOT compiled from day 1, just like many other alternatives that used to exist, C++ might have not taken off as it did.
The rise of VM languages, with other AOT compiled languages fading away and rise of FOSS written mostly in C, made C and C++ the only languages we could turn to when the performance was lacking, thus arriving at the actual situation.
As for using C with a scripting language, without the safety of strong type checking, real enumerations, support for arrays and strings, no namespaces, no RAII, new/delete instead of malloc()/free() and many of safety improvements from C++ over C, that is not something I will ever advise.
I already did that once with Tcl for two years, no need to repeat it.
Re: An empirical study on the impact of C++ lambdas and programmer experience
#90Earlier quoted context omitted.
"Idiomatic" doesn't necessarily mean better. I think objectively it's hard to argue that "item != market.end()" is superior to "iter.hasNext()". The latter accurately reflects the programmer's intent, while the former specifies an unnecessarily specific (and poor) implementation of the intent. First of all, using something like "market.cend() != const_iter" instead is arguably better practice (imagine you unintention…
> "Idiomatic" doesn't necessarily mean better. I think objectively it's hard to argue that "item != market.end()" is superior to "iter.hasNext()". The latter accurately reflects the programmer's intent, while the former specifies an unnecessarily specific (and poor) implementation of the intent At this point, I find the former much more readable than the latter. I have seen the former a thousand times. I have seen th…
Yeah, after further consideration I'm not convinced either.