From Java to C++ - lambdas
Tags: cpp, lambda, java, functional
Published: 2021-11-26 11:08:48

<p style="text-align: justify;">In Java, we have our take on functional programming with <strong>lambdas</strong>. Obviously, as functional programmers love to tell us - they're just a mere simplifications of the 'real' functional languages. However, introduced in Java 8, they've had  really changed how we do things in Java now. As for C/C++, functions were there from the very beginning  (obviously!), but concepts of <strong>lambdas</strong> emerged just in the latest C++20 standard.</p>
<p style="text-align: justify;">In this post I will try to take more broad approach to the concepts of <strong>functions</strong> and <strong>lambdas</strong> in C++. I've thought about writing about C <em>function pointers</em>, but I've decided to just refresh my memory with <strong>Richard Reese</strong>  <em>Understanding and using C pointers'</em> book, but do not write about it here. Let's keep it pure C++, and concentrate on more abstract solutions. Like the one just coming in our way - functions as objects.</p>

<h2>Function as an object</h2>
<p style="text-align: justify;">The concept of functions being <em>first class citizens</em> in the programming languages has a long tradition. In order to achieve that in C++, we need a way to pass functions to the methods as params. A universal container for callable objects is <em>std::function</em> class - wrapper around <em>function pointer</em>. It's a piece of standard library, residing in the <em><functional> header</em>. I'm starting with it, as it is more generic than <strong>lambdas</strong>.</p>
<p style="text-align: justify;">In general, it's possible to create an empty <em>std::function</em> object, but that won't be much of use - trying to call such object will result in <em>std::bad_function_call</em> exception being thrown. What we need, is object that actually holds a callable 'thing'. There are two ways to assign a callable object to the <em>std::function</em> instance - either as a constructor param, or just by assigning it to the pointer. Here's an example:</p>


```cpp
#include <iostream>
#include <functional>

void testFunction()
{
    std::cout << "Test function";
}

int main()
{
    std::function<void()> testFunctionHandler { testFunction };
    std::function<void()> testFunctionHandler2 = testFunction;

    testFunctionHandler();
    testFunctionHandler2();
}
```

<p style="text-align: justify;">It does not look scary - maybe syntax is a little weird, but nothing we cannot handle. <em>std::function</em> can serve as w convenient abstraction, representing all the types of callable things. However, here's the more modern approach to functional programming in C++ (and more close to Java equivalent) - <strong>lambdas</strong>.</p>

<h2>Lambdas in C++</h2>
The same as in Java, it's a popular use case, to just pass some behaviour represented by a function. We don't need to (or don't want to), create a separate function or an object for that. What we want, is to pass some behaviour to the method and let it do its job. That's what <strong>lambdas</strong> are for - simple (ok, got me) concepts of passable behaviour. Let's start with the most simple example of a function - that takes nothing and returns nothing (besides side-effect):

```cpp
#include <iostream>

void printSomeMsg() {
    std::cout << "Some message" << std::endl;
}

int main() {
    printSomeMsg();
}
```

As simple as it is - it just prints the hardcoded message. However, let's assume that we don't want to write such a trivial function in our code. We just need its functionality in the specific places. That's where the lambda comes in. Let's take a look at this:

```cpp
#include <functional>
#include <iostream>

int main() {
    auto ourLambdaAsAuto = []() { std::cout << "Some message" << std::endl; };
    std::function<void()> ourLambdaAsFunction = []() { std::cout << "Some message 2" << std::endl; };

    ourLambdaAsAuto();
    ourLambdaAsFunction();
}
```

Again, the syntax may look scary at the beginning, but that's not that big of a deal. Let's go through it step by step:
<ul>
 	<li><strong>[]</strong> - it is empty now, but that does not mean it's not being used. These square brackets are responsible for specifying <strong>captures</strong>. In simple words - they fetch needed data/variables from the calling context. We will discuss this in detail later, as it is quite important.</li>
 	<li><strong>()</strong> - rather familiar feature. In the simple parenthesis we just specify arguments to the lambda. We don't have any here, that's why it's empty.</li>
 	<li><strong>{}</strong> - in the curly braces we provide the body of our lambda. In short - the job to be done.</li>
</ul>
<p style="text-align: justify;">Wasn't that bad, right? Of course, our simple example did not cover everything. Generic expression for lambda creation looks like this:</p>


```
[captures] (parameters) modifiers -> return-type { body }
```

From the above expression we know already <em>captures, parameters</em> and <em>body</em>. The remaining two are quite simple:
<ul>
 	<li><strong>modifiers</strong> - we can specify different modifiers, but depending on the standard they may vary, and their behaviour too. The best way to learn about them is to visit <a href="https://en.cppreference.com/w/cpp/language/lambda">official C++ ref docs</a>. The most popular are <strong>const</strong> and <strong>constexpr</strong>.</li>
 	<li><strong>return type</strong> - by default the compiler will deduce the return type of the lambda. However, especially when we're using template lambdas, it's advisable to help the compiler with small hint. Like in this example:

<em>
[](auto x, double y) -> decltype(x+y) { return x + y; }
</em>

</li>
</ul>
<h3>More about lambdas params</h3>
<p style="text-align: justify;">Parameters to <strong>lambdas</strong> are not that different from the regular ones. That means, we can both assign to them default values, and use <em>auto</em> type. Slightly modified example taken from <em>'C++ Crash Course'</em> shows these two in combination.</p>


```cpp
#include <iostream>

int main() {
    auto increment = [](auto x, int y = 1) { return x + y; };
    std::cout << increment(10) << std::endl;
    std::cout << increment(10, 5) << std::endl;
}
```

<h3>Lambda captures</h3>
<p style="text-align: justify;">Remember these square brackets that up until now we've always left empty? Now the time has come to tell something more about them. <strong>Captures</strong> are quite important for <strong>lambdas</strong>, as they allow them to have context passed. Let's start with simple example.</p>


```cpp
#include <iostream>

class MySimpleClassPiece {
    public:
        int x;
        std::string someStringValue;
};


class MySimpleClass {
    public:
        MySimpleClassPiece piece;
};



int main() {
    MySimpleClass mySimpleClass { MySimpleClassPiece {1, "someStringValue"} };

    std::cout << mySimpleClass.piece.someStringValue << std::endl;
    std::cout << mySimpleClass.piece.x << std::endl;
}
```

<p style="text-align: justify;">Everything here is public, for the sake of simplicity. Printing to the standard output is done directly in the <em>main </em>function, and that is not what we want in the long run. Let's assume, that based on some logic, we want to either print the object state to the console, or modify the values in the object. As this is purely behaviour-driven thing, we're going to use lambdas for this. Let's start with the printing piece first.</p>


```cpp
// Everything besides main() is the same as above
int main() {
    MySimpleClass mySimpleClass { MySimpleClassPiece {1, "someStringValue"} };
    auto printingLambda = [mySimpleClass]() {
        std::cout << mySimpleClass.piece.someStringValue << std::endl;
        std::cout << mySimpleClass.piece.x << std::endl;
    };
    printingLambda(); 
}
```

<p style="text-align: justify;">Running above code snippet produces the same output as before. What happened here? In general, in the <strong>capture</strong> section of a <strong>lambda</strong>, we can put whatever parameters we want, and what is more, we can select variables from the calling context, to pass into the <strong>lambdas' body</strong> (as presented above). By default, all the variables <strong>are passed by value!</strong></p>
Of course, we're not limited to just passing the value - we can change its name. It is done like this:

```cpp
int main() {
    MySimpleClass mySimpleClass { MySimpleClassPiece {1, "someStringvalue"} };
    auto printingLambda = [externalVariable=mySimpleClass]() {
        std::cout << externalVariable.piece.someStringValue << std::endl;
        std::cout << externalVariable.piece.x << std::endl;
    };
    printingLambda();
}
```

<p style="text-align: justify;">Using this technique can improve the readability of the code, especially when the <strong>lambda</strong> is contained within the same compilation unit. But that's not over! When it comes to parameters, we can also provide new ones, completely unrelated to the context variables.</p>


```cpp
int main() {
    MySimpleClass mySimpleClass { MySimpleClassPiece {1, "someStringvalue"} };
    int xx = 5;
    int zz = 10;

    auto printingLambda = [externalVariable=mySimpleClass, y = 1, z = 5, result = xx + zz]() {
        std::cout << externalVariable.piece.someStringValue << std::endl;
        std::cout << externalVariable.piece.x << std::endl;
        std::cout << y + z << std::endl;
        std::cout << result << std::endl;
    };
    printingLambda();
}
```

This piece of code will actually print:
<pre>someStringvalue
1
6
15
</pre>
<p style="text-align: justify;">As you can see this feature is quite powerful, and enables <strong>lambda</strong> to get as much data as needed, to perform a specific operation. However, up until now we're operating with <em>named parameters</em> - we're specifying all of them in the <em>captures</em> section. That gives us a lot of flexibility, but sometimes we just want to pass everything to the <strong>lambda</strong> at once. We don't want to provide variables one by one, or (in the future), have to add additional params when new variables appear.</p>
<p style="text-align: justify;">The way to achieve that, is to use 'wildcard-style' in the square brackets. By putting there <em>'='</em> sign, we pass to the lambda all the variables that enclosing context contains, and lambda wants to use. As simple as that:</p>


```cpp
int main() {
    MySimpleClass mySimpleClass { MySimpleClassPiece {1, "someStringvalue"} };
    int xx = 5;
    int zz = 10;
    int result = xx + zz;

    auto printingLambda = [=]() {
        // Pay attention that we have to use the name of the original variable here! 
        std::cout << mySimpleClass.piece.someStringValue << std::endl;
        std::cout << mySimpleClass.piece.x << std::endl;
        std::cout << result << std::endl;
    };
    printingLambda();
}
```

<p style="text-align: justify;">It makes the code easier to maintain, but as I've said - it may influence the readability. Therefore, it's always situation based, whether we use <em>default capture</em> or <em>named one</em>. Ok, so far we've been dealing with parameters' values, as by default the parameters are passed by values. What if the <strong>lambda</strong> wanted to actually modify them? Trying to do that in the above example will fail.</p>


```cpp
auto printingLambda = [=]() {
    std::cout << mySimpleClass.piece.someStringValue <<; std::endl;
    std::cout << mySimpleClass.piece.x << std::endl;
    std::cout << result << std::endl;
    result = 14;   // Results in compilation error with:  assignment of read-only variable 'result'
};
```

<p style="text-align: justify;">If we want to make modifications to the variables, we could fall in a nasty trap here. I've mentioned in the list above, that one part of <strong>lambda</strong> expression can belong to <strong>modifiers</strong>. One of them is actually <strong>mutable</strong>. Sounds about right! Let's take a look at the following code, and try to predict how it behaves.</p>


```cpp
int main() {
    int toAdd = 0;

    auto printingLambda = [=]() mutable {   //  mutable added 
        toAdd += 5;
        std::cout << toAdd << std::endl;
    };

    printingLambda();
    std::cout << "In main: " << toAdd << std::endl;
    printingLambda();
    std::cout << "In main: " << toAdd << std::endl;
    printingLambda();
    std::cout << "In main: " << toAdd << std::endl;
}
```

If you've expected ever-increasing output I have bad news for you. It actually looks like this:
<pre>5
In main: 0
10
In main: 0
15
In main: 0
</pre>
<p style="text-align: justify;">Weird, isn't it? The problem here is, that <strong>mutable</strong> does not allow modifying params passed by values - quite reasonable I would say. What it does instead, is that it creates a new variable named exactly as the one used (in this example it is <strong>toAdd</strong>), and then keeps it in memory, as long as <strong>lambda</strong> is in use. That explains how we got this specific output.</p>
<p style="text-align: justify;">All right, but what if I want to modify actual variables from the outside world. Well, that's not a problem - just pass them as references. We can do that by replacing <em>'='</em> sign with <em>'&amp;'</em> one.</p>


```cpp
int main() {
    int toAdd = 0;

    auto printingLambda = [&amp;]() {
        toAdd += 5;
        std::cout << toAdd << std::endl;
    };

    printingLambda();
    std::cout << "In main: " << toAdd << std::endl;
    printingLambda();
    std::cout << "In main: " << toAdd << std::endl;
    printingLambda();
    std::cout << "In main: " << toAdd << std::endl;
}
```

With that change, our output looks like we wanted it for the first time:
<pre>5
In main: 5
10
In main: 10
15
In main: 15
</pre>
What must be said here, is that we're not limited to either <em>named captures</em> and <em>default ones</em>! We can mix them for every <strong>lambda</strong>! Here's an example:

```cpp

int main() {
    int toAdd = 0;
    int x = 5;

    auto printingLambda = [=, &amp;toAdd]() {
        toAdd += 5;
        std::cout << toAdd << std::endl;  // toAdd passing/changes will work as in the previous example

        std::cout << x << std::endl;
        // x += 10;   This line will cause compiler to fail
    };

    // printing skipped
}
```

<p style="text-align: justify;">To finish discussing <strong>captures</strong> I have to mention, that it's also possible to pass to the <strong>lambda</strong> (either by value or by reference), an actual instance of the wrapping class. However, the topic is not trivial - I recommend reading <a href="https://www.nextptr. com/tutorial/ta1430524603/capture-this-in-lambda-expression-timeline-of-change">an excellent article on Nextptr.com</a>. What is more - linked presentation in the sources section also provides valuable info about it. That's it for today.</p>
SOURCES:
<ul>
 	<li><a href="https://lp.embarcadero.com/cpplambdasebook">Free ebook about lambdas</a> - whole book dedicated to lambdas in C++. Just provide email address and it's yours.</li>
 	<li><a href="https://www.youtube.com/watch?v=3jCOwajNch0&amp;ab_channel=CppCon">Introduction to lambdas</a> - BackToBasis series on CPPConf</li>
 	<li><em>'Understanding and using C Pointers'</em> by Richard Reese, chapter about function pointers</li>
 	<li><em>'C++ Crash Course' </em>by Josh Lospinoso</li>
 	<li><a href="https://www.nextptr. com/tutorial/ta1430524603/capture-this-in-lambda-expression-timeline-of-change">Nexptr.com article</a> about the evolution of <em>this</em> capturing</li>
</ul>