A blog on various topics in C++ programming including language features, standards, idioms, design patterns, functional, and OO programming.

Wednesday, March 12, 2014

Fun with Lambdas: C++14 Style (part 1)

It's common knowledge that Functional Programming is spreading like a wildfire in mainstream languages. Latest promoted languages: Java 8 and C++, both of which now support lambdas. So, let the lambdas begin! and may the fun be ever on your side. The same text is available in slides form on Slideshare. This blog post and the talk/slides are inspired by JSON inventor Douglas Crockford.

Write an Identity function that takes an argument and returns the same argument.

auto Identity = [](auto x) {
return x;
};
Identity(3); // 3

Write 3 functions add, sub, and mul that take 2 parameters each and return their sum, difference, and product respectively.

"A lambda is just an anonymous function." -- I understand the desire to make the explanation as simple as possible, but here it happens at the cost of correctness. "Just functions" don't carry state. Perhaps "A lambda is just a syntax sugar to define anonymous functions and function objects"?

"Not all closures are lambdas and not all lambdas are closures." -- sounds weird. A lambda is a syntactic construct (expression), and a closure is a run-time object, an instance of a closure type. Neither can "be" the other.

Jumping on the back of @joaof's comment: Using decltype to ascertain the type of auto x allows for using an interesting pattern of, what the D Language community calls, Voldemort types. Walter Bright wrote an interesting article about it which you can read here.

Interesting to note that, unlike in D, we can later retrieve the type of Inner outside of the lambda:

@dave Aliasing the type of lambda is fine but are you sure about the rest? I get compiler error for "Foo bar(10)" and is_constructible returns false. Besides, there are many limitations like missing copy-assignment operator for lambdas. class Inner, however it copy-assignable.

The point is that c++ lambdas are *not* closures because they just honor the external lifetime of the object without making sure the object survives as long as the lambda does. In c++ one way to lengthen an object's lifetime is to make it a shared pointer, which is reference counted.