The Register® — Biting the hand that feeds IT

Feeds

C++ Futures: Lambda Functions

Like the Lambada, only different

Free ESG report : Seamless data management with Avere FXT

Column The use of “lambda” originates from functional programming and lambda calculus, where a lambda abstraction defines an unnamed function. Lambda functions or Lambdas in C++ are one of the more interesting things to look forward to in the next C++ standard; giving us the ability to treat functions as first class objects at last; composing them inline and treating them as class objects. Up until now we've scraped by with pointers to functions, and various libraries like Boost Lambda, both of which approaches suck.

The syntax for declaring function pointers can get so cryptic that at a large percentage of C++ interviews, it's used to filter out the weak applicants. Boost et al. do a good job given the limits of the language; but again if you try anything more ambitious than a simple predicate then debugging can get very painful. They offer, as Valentin Samko says with heavy irony in his proposal here, the opportunity to learn "numerous highly non-trivial programming techniques".

All by themselves they beat the amateur efforts in the International Obfuscated C contest. However, it would be nice to be able to write something like this (where the code is passed just as if were any other type of variable):

 void KillByVal(const int x , std::vector<int> & Vec) {
 std::remove_if(v.begin(), v.end(), bool (int& n) { n == x; }
 };

The first thing to notice is that the predicate we supply can see the parameter x directly. Lambdas will naturally have the scope of the enclosing function, and since they aren't full classes will include the local this pointer without clashing. This style of coding is giving a big hint to the compiler for inline optimisations.

Before I get letters of complaint, yes I know you can do some of this with #define, but if you know how to do this, you also know why it's such a tragically bad idea.

Loopless code

Explicit loops are not just sources of the "out by one" family of bugs, but also are often less efficient than the STL algorithms, a fact that is, surprisingly, still unknown to a good percentage of programmers.

I adhere to the notion that the closer the mapping between intent and implementation, the better the code. You may not agree; if so, that's presumably why you're still using MFC. However, to many people it is more intuitive to "apply" code to a set of data, saying in effect "do this action to it", rather than to explicitly iterate though each value. This is not only because it feels more elegant, but also because if you don't specify a deterministic sequence, a smart compiler with access to multiple CPU cores or hardware assist (as in GPUs, PPU or SIMD architectures) can generate much better code. Even my laptop now has twin cores (if yours doesn't, I win) – and by the time this stuff hits your compiler, multiple CPUs will be very common. STL already makes use of function objects for a variety of For_Each replacements for the classic C style loop.

Another way in which functors and function pointers are weak is in not meshing with the scope of the code you're writing. Since they are in a separate context, they simply cannot know about variables local to their invocation unless you're dumb enough to use globals to communicate with them.

Lambdas will enjoy access just as if they were a block within the scope of a function body; and that includes access to this when it's a class member; but since a lambda isn't quite a class it has no this pointer to clash with it.

Nevertheless, being an object, a Lambda's lifetime isn't bounded to the function in which it is created, and so, even before compilers support this feature, we have a new variant on an old type of bug. Just like pointers to local objects, Lambdas may reference variables and continue to do so after it is no longer safe; and, before you ask, even the smartest compiler can't catch all cases. There is now a serious debate on how variables get into the Lambda: should they be copied or referenced? References are more dangerous, but, in many cases, vastly more efficient than copies for larger objects; but the copies are vastly easier to multi thread.

Lambdas will be declared with much the same syntax as you'd expect for a function, taking forms like:

 Return_Type Name (Type1 P1,.TypeN PN);
<> (Type1 P1, Type2 P2, ...)

For example:

<> (auto x, auto& y) { y += x; } is equivalent to template<class T1, class T2> void (T1 x, T2& y) { y += x; }

And a return type is only necessary if it cannot be deduced (normally, it's prefixed by ->). This means that the compiler can immediately recognise that it’s not an older style function, which should make error messages more comprehensible.

We currently use function names to reference the address of piece of code when creating thread procs or callbacks, again making encapsulation more clunky. Most O/S level thread and callback APIs don't really handle the passing of parameters to their functions well, mostly because of irritating stack issues; and also because, in their heart of hearts, both Windows and UNIX are really still C APIs.

As a side effect of this, Lambda objects also refer to a specific context of execution; so two Lambda objects created by the same or identical code may refer to two different contexts of execution, and therefore different sets of local variables:

 APICreateThread ( tr1::function<void(int)>)

 CFeed::FireThread (int ct)
 {
 APICreateThread (void(int i) : (Repeat (ct)) { for (int i=0; i!=ct; ++)
 DoStuff(); });
 }

Old function pointers may point anywhere, with zero often being used to mean “uninitialised” — and of course that means every so often you end up jumping to zero and dying horribly. Lambdas, on the other hand, are more like references than pointers in that they must point to some block of code; and not being pointers stops people coding atrocities like address arithmetic before calls.

You cannot do address arithmetic on function pointers unless you reinterpret_cast them, but then you get what you deserve.

Lambdas look likely to be in C++Ox, but work is still under way, and the committee is planning to review refined versions relatively soon. And, just to refer back to my provious C++ divided by CLI article, the committee has rejected Microsoft’s proposal. I really can’t decide whether that’s good or bad, so I'll just end here, I think.

5 ways to reduce advertising network latency

Whitepapers

Microsoft’s Cloud OS
System Center Virtual Machine manager and how this product allows the level of virtualization abstraction to move from individual physical computers and clusters to unifying the whole Data Centre as an abstraction layer.
5 ways to prepare your advertising infrastructure for disaster
Being prepared allows your brand to greatly improve your advertising infrastructure performance and reliability that, in the end, will boost confidence in your brand.
Reg Reader Research: SaaS based Email and Office Productivity Tools
Read this Reg reader report which provides advice and guidance for SMBs towards the use of SaaS based email and Office productivity tools.
Email delivery: Hate phishing emails? You'll love DMARC
DMARC has been created as a standard to help properly authenticate your sends and monitor and report phishers that are trying to send from your name..
High Performance for All
While HPC is not new, it has traditionally been seen as a specialist area – is it now geared up to meet more mainstream requirements?

More from The Register

next story
Windows 8 fans out-enthuse Apple fanbois
Redmond allows 81 Win 8 devices to use one user ID, solving side-loading shemozzle
'200 million' fanbois using iOS 7 just a week after release - study
Plus: Most US iDevice users are drinking Cupertino's latest Koolaid
No luck at all for BlackBerry as Messenger apps launch stalls
Leaked Android build 'causes issues,' is withdrawn
App Store ratings mess: What do we like? Sigh, we dunno – fanbois
How do I know what to download if I don't know what everyone else is doing?
OUCH: Google preps ad goo injection for Android mobile Gmail app
Don't worry, fandroids, wallet-plumping serum won't hurt a bit
Launchpads, catapults... what a load of - WAIT, there's £15m for grabs?
Quango sprinkles cash on games, animation and trendy meeja types
Apple iOS 7 makes some users literally SICK. As in puking, not upset
'Eye candy really is as bad as classical candy is for the teeth,' writes one
Google reveals its Hummingbird: Fly, my little algorithm - FLY!
Update brings Googleplex one step closer to sentience
Oracle hides ExaLogic price cut
Old price lists prove price halved, so why has Big Red deleted the post announcing it?
prev story