I agree with everything, but I think there's one other thing that's worth pointing out about lambdas, especially how they differ from function pointers: They're *usually* implemented as closures, meaning that they close over the scope where they're defined, allowing you to capture variables from an outer scope
Some languages (such as C#) does this automatically, for instance:
var n = 2;
// Print all even numbers
Enumerable
.Range(0, 100)
.Where(i => i % n == 0)
.ToList()
.ForEach(Console.WriteLine);
In this case, the following:
i => i % n == 0
... is an anonymous function, but it also allows you to capture and use the variable 'n', even though it's defined outside of the function's scope. This works well in a lot of languages (Python, Lua, JavaScript, Lisp etc...)
Some languages, such as C++11, allows you to do this, but you need to explicitly declare what to capture. Here's a few various C++ lambdas:
[](){} // Simplest possible lambda:
// Description: [] = capture list, () = parameter list, {} = function body
[&x](){} // A lambda capturing the variable x by reference,
// allowing you to use it in the function
[x](){} // A lambda capturing the variable x by copy
[=](){} // A lambda capturing everything from the outer scope by copy
[&](){} // A lambda capturing everything from the outer scope by reference
[this](){} // A lambda capturing the this pointer
The neat thing about this is that lambdas are literals in the same sense as other values that you can store in variables, allowing you to write functions that either take other functions as arguments (and still having access to the captured variables), or even functions having functions as return values.
As an example, I make use of a bunch of timers in my current engine, where I provide a callback once the timer has finished. The code usually looks like this:
interval.onDone([this](){
evt->dispatch(Event::QuakeOccured(0.5, false, Event::QuakeOccured::WAVELET, 0.3f));
audio->playSoundFx(AudioType::THUNDER);
// ... More code here
});
In this case, the function is actually called inside the timer (the interval instance), but once run, it will still be able to access the evt and audio variables, even though they're actually fields in the class where the lambda is defined, basically giving you
deferred execution.
Just a few quick and dirty examples. Could probably scrounge up a few more ones that's a bit more well thought out
tl;dr: Lambdas and closures allow you to factor out flow control.