Closures are complicated
C is and always has been a simple language, and it tries to remain that way even today. If you wanted to add the ability to make simple non-closing functions as local variables, that's easy and wouldn't affect the semantics of the language in the slightest. A non-closing function would simply compile to a top-level static
function with a generated name and would only be accessible inside of the scope it was defined in.
However, generally when people want anonymous functions, what they really want is closures. Closures can use local variables in the surrounding scope, in addition to the data globally available in the current file. That's what allows tricks like
def add_to_each(lst, number):
return map(lambda x: x + number, lst)
to work. The lambda
here closes around the variable number
. It's no longer just an ordinary function in the machine sense of the word; now it's a function plus some extra state.
In C++, if you create a lambda that doesn't close around any variables, it's guaranteed to be available as a function pointer, i.e. a plain old ordinary C++98-style function. But if you need a nontrivial closure, then C++ does magic to make a strange object that just works the way you expect. That object's type is no longer int(*)(int, int)
. Its type is in fact special-made just for this situation, and you can't refer to it by name (though it is convertible to std::function<int(int, int)>
, which is another piece of C++ magic). All of this is fine in C++, which is "C plus insane high-level shenanigans". But C is designed to be simple and predictable, so the language avoids adding all of this code generation for the same reason templates were never added to C: it would just add so much complexity.