I think the OP makes it clear that this nuance is actually quite tricky in a native systems language like Rust.
A good example in C++ would be:
- A function (non capturing/lambda) is created with
auto f = [] { ... };
- A function (capturing/closure) is created with
auto s = "...";
auto f = [&] { s; ... };
In source code both of those look similar and you can even define them with the same type: std::function<void()>
However, the resulting assembly for both couldn't be more different. The Lambda case is as raw as any normal C function type, which the closure case creates a C++ class that closes over the outer method's state. If you're not a seasoned C++ engineer, this nuance will be lost on you.
It's fair to say that everyone should understand Lambda Calculus rules, but that makes the language less accessible to new-comers. In the case for non-systems languages, you can blur the lines with ease, but something Rust and C++ just cannot afford to do. That makes understanding the nuance important to be effective.
I’m pretty sure that the generated assembly for both your examples written as-is is the same. The optimizer should see through the lambda sugar unless the example gets weird or you type-erase via std::function.
I think your broader point still holds but perhaps could do with a clearer example
A good example in C++ would be:
- A function (non capturing/lambda) is created with
- A function (capturing/closure) is created with In source code both of those look similar and you can even define them with the same type: std::function<void()>However, the resulting assembly for both couldn't be more different. The Lambda case is as raw as any normal C function type, which the closure case creates a C++ class that closes over the outer method's state. If you're not a seasoned C++ engineer, this nuance will be lost on you.
It's fair to say that everyone should understand Lambda Calculus rules, but that makes the language less accessible to new-comers. In the case for non-systems languages, you can blur the lines with ease, but something Rust and C++ just cannot afford to do. That makes understanding the nuance important to be effective.