There's certainly a noticeable trend towards functional programming, or at least certain aspects of it. Some of the popular languages that at some point adopted anonymous functions are C++ (C++11), PHP (PHP 5.3.0), C# (C# v2.0), Delphi (since 2009), Objective C (blocks) while Java 8 will bring support for lambdas to the language . And there are popular languages that are generally not considered functional but supported anonymous functions from the start, or at least early on, the shining example being JavaScript.
As with all trends, trying to look for a single event that sparked them is probably a waste of time, it's usually a combination of factors, most of which aren't quantifiable. Practical Common Lisp, published in 2005, may have played an important role in bringing new attention to Lisp as a practical language, as for quite some time Lisp was mostly a language you'd meet in an academic setting, or very specific niche markets. JavaScript's popularity may have also played an important role in bringing new attention to anonymous functions, as munificent explains in his answer.
Other than the adoption of functional concepts from multi-purpose languages, there's also a noticeable shift towards functional (or mostly functional) languages. Languages like Erlang (1986), Haskell (1990), OCaml (1996), Scala (2003), F# (2005), Clojure (2007), and even domain specific languages like R (1993) seem to have gained a strong following strongly after they were introduced. The general trend has brought new attention to older functional languages, like Scheme (1975), and obviously Common Lisp.
I think the single more important event is the adoption of functional programming in the industry. I have absolutely no idea why that didn't use to be the case, but it seems to me that at some point during the early and mid 90s functional programming started to find it's place in the industry, starting (perhaps) with Erlang's proliferation in telecommunications and Haskell's adoption in aerospace and hardware design.
Joel Spolsky has written a very interesting blog post, The Perils of JavaSchools, where he argues against the (then) trend of universities to favour Java over other, perhaps more difficult to learn languages. Although the blog post has little to do with functional programming, it identifies a key issue:
Therein lies the debate. Years of whinging by lazy CS undergrads like me, combined with complaints from industry about how few CS majors are graduating from American universities, have taken a toll, and in the last decade a large number of otherwise perfectly good schools have gone 100% Java. It's hip, the recruiters who use "grep" to evaluate resumes seem to like it, and, best of all, there's nothing hard enough about Java to really weed out the programmers without the part of the brain that does pointers or recursion, so the drop-out rates are lower, and the computer science departments have more students, and bigger budgets, and all is well.
I still remember how much I hated Lisp, when I first met her during my college years. It's definitely a harsh mistress, and it's not a language where you can be immediately productive (well, at least I couldn't). Compared to Lisp, Haskell (for example) is a lot friendlier, you can be productive without that much effort and without feeling like a complete idiot, and that might also be an important factor in the shift towards functional programming.
All in all, this is a good thing. Several multi-purpose languages are adopting concepts of paradigm that might have seemed arcane to most of their users before, and the gap between the main paradigms is narrowing.
Related questions:
Further reading:
Both solutions make sense, and have different tradeoffs.
Lambdas
The style of using lambdas inside another function is very common across many languages. If it seems alien to you, that's just because lambdas weren't available in C++ until recently. The advantage of this style is that the whole implementation of the function is within that function, with the lambda grouping repeated behaviour into a single block. Since the lambda can capture local variables (cont
in your case), you will not typically have to pass many arguments. Drawbacks are that this function can still grow rather longish, and that you can't independently test the extracted behaviour.
Named functions
If you use a proper function (either a free function in an anonymous namespace, or a private member function), then your main function becomes less cluttered, and the extracted behaviour is independently testable. This extract-function refactoring is incredibly common, and makes it a breeze to test and understand the code: Each function is only a couple of lines long. And with proper names, such code becomes highly self-documenting.
However, parts of the behaviour are now strewn all over the place, and forming a complete understanding of the behaviour requires a reader to stitch together all these bits and pieces – too much abstraction can result in a loss of maintainability. Also, the previously internal code can be now called from any other function within its scope, which means that invariants that are obvious within local usage are now not guaranteed and have to be re-checked if you are interested in correct code, e.g. asserting that a pointer is non-null. Finally, an important downside is that any context which the function operators on has to be passed explicitly as an argument. This can become tedious for 5–8 arguments, since C++ does not have named formal parameters :(
For-loops
Another possibility, more like creating a lambda, is storing the data you are operating on in a vector, and then performing an action on each item via a loop. E.g.:
std::vector<WorkItem> items {
{true, 42},
{false, 128},
};
for (const auto& item : items) {
...
}
Often, the work item type might just be a tuple or pair. I'm not too fond of this solution since the ordering of the code is a bit unintuitive, but it's an effective method to get repeated code out of the way.
Personal opinion
When I extract behaviour into a separate function, I first tend to use a lambda since the advantage of capturing local variables is tremendous. However, in later refactorings I tend to use named functions so that I can test them more easily. For me, this outweighs the cost of losing context.
Best Answer
Quite frankly, that's their problem. That's what you ensure they have training for. You can't not use a good technique just because some people might not understand it. If they need help with it, they can come ask the author. More importantly, lambda functions are becoming extremely common language features.
Should we not use inheritance because some people don't understand it? Hell, some people refuse to believe in science or germs or any manner of ridiculous things. You have to be able to move on and not let the possibility that others won't be able to keep up with you stop you from writing the best code you can. Lambda functions are a great feature and greatly help in writing code, and you should take all the help you can get.
A developer should know how to use the language they're in- junior or not. If they don't, then fire them and find someone who does, or train them up so they do.