Lambdas vs Closures

Today's article is a short one from Scott Meyers. I did not actually know the difference between a "lambda" and a "closure" and considered myself enlightened after reading. Hopefully some of you will find this equally interesting.

tl;dr:

the expression to the right of the "=" is the lambda expression (i.e., "the lambda"), and the runtime object created by that expression is the closure.

auto f = [&](int x, int y) { return fudgeFactor * (x + y); };
Read "Lambdas vs Closures" here

My Highlights

[Given the statement below], the expression to the right of the "=" is the lambda expression (i.e., "the lambda"), and the runtime object created by that expression is the closure.

auto f = [&](int x, int y) { return fudgeFactor * (x + y); };

You could be forgiven for thinking that, in this example, f was the closure, but it's not. f is a copy of the closure. The process of copying the closure into f may be optimized into a move (whether it is depends on the types captured by the lambda), but that doesn't change the fact that f itself is not the closure. The actual closure object is a temporary that's typically destroyed at the end of the statement.

The distinction between a lambda and the corresponding closure is precisely equivalent to the distinction between a class and an instance of the class. A class exists only in source code; it doesn't exist at runtime. What exists at runtime are objects of the class type. Closures are to lambdas as objects are to classes. This should not be a surprise, because each lambda expression causes a unique class to be generated (during compilation) and also causes an object of that class type--a closure--to be created (at runtime).

Answering a commentor's question, "Why do I care?":

The purpose of language is communication, and as long as you and your coworkers understand one another, it doesn't matter if you draw a distinction between lambdas and closures. Many people call both a lambda and live happy, fulfilling lives. In my experience, the more technical the discussion (especially as regards compilation, code generation, and runtime entities), the more important it is to be precise about what you're referring to. Lambdas occupy no data memory at runtime, for example, though they may occupy code memory. Closures occupy data memory, but not code memory.