Anonymous Function

Anonymous functions don’t have names. I first learned about this at Marianopolis College programming class, but it was actually super easy.

I wonder if every single person in that class went into Software Engineering / Computer Science lol.

Python

Something like this

a = lambda x: x+2
print(a(5)) # Output: 7

C++

https://stackoverflow.com/questions/7100889/how-can-i-access-local-variables-from-inside-a-c11-anonymous-function

Used for the first time when I was trying to write ORB-SLAM from scratch.

Anatomy of lambda function

  1. Capture clause (Also known as the lambda-introducer in the C++ specification.)
  2. Parameter list Optional. (Also known as the lambda declarator)
  3. Mutable specification Optional.
  4. Exception-specification Optional.
  5. trailing-return-type Optional.
  6. lambda body.
float tot = std::accumulate(weights.begin(), weights.end(), 0);
 
std::transform(weights.begin(), weights.end(), [tot](float x)->float{return(x/tot);});

In this case tot is captured by value. C++11 lambdas support capturing by:

  1. value [x]
  2. reference [&x]
  3. any variable currently in scope by reference [&]
  4. same as 3, but by value [=]

You can mix any of the above in a comma separated list [x, &y].

Tip

Using the third way [&] is generally considered bad practice, because you aren’t explicit about the variables that you want to use.

I don't get the capture clause vs. parameter list? What is the difference?

The parameter list is the list of parameters you pass to the lambda function when it comes times to calling it. The capture clause lists out variables that can be used inside the lambda function (essentially extending the scope of the variable).

Why use the capture clause when it can be passed in the parameter list?

This is a good question. I found a stack overflow answer.

Here’s a good example of where you need capture clause:

std::vector<double> v{ 1.0, 2.2, 4.0, 5.5, 7.2 };
double r = 4.0;
std::for_each(v.begin(), v.end(), [&](double &v) { v += r; });
  • in this case, for_each expects a function that takes in a single value of the type of array, and applies it
  • You can’t pass r into the argument list, since when the for_each function is defined, it works for a UnaryFunction (see below)
    • It’s sort of equivalent to using std::bind (C++)

Capture clauses thus introduce a new level of abstraction that one can make use of.

This is how it’s implemented under the hood

template<class InputIt, class UnaryFunction>
UnaryFunction for_each(InputIt first, InputIt last, UnaryFunction f)
{
  for (; first != last; ++first) {
    f(*first);
  }
  return f;
}
### Related


Example
```cpp
auto myLambda = [](int a, int b) {
    return a + b;
};

myLambda(5, 10);  // 15

With a capture clause

int x = 10;
auto myLambda = [x](int a) {
    return a + x;
};

Are we supposed to use the auto keyword?

Ya. Under the hood, its a std::function.

To access local variables from within anonymous function, you need a Closure.