The new C++11 standard supports lambda functions, which I think is a useful feature. I understand that the C and C++ standards differ from each other but I don't understand why C11 doesn't support lambda functions. I think it could have a lot of use.
Is there a reason why the developers of the C11 standard choose not to include this feature?
This is really just my opinion, since I don't know what the committee thinks.
On the one hand, Lisp has been supporting lambda expression since its birth, which is in 1958. The C programming language was born in 1972. So lambda expression actually has a longer history than C. So if you ask why C11 doesn't support lambda expression, the same question can be asked about C89.
On the other hand, lambda expression is always a functional programming thing, and is absorbed to imperative programming languages gradually. Some of the "higher" language (e.g, Java, before the planned Java 8) doesn't support it yet.
Finally, C and C++ are always learning from each other, so maybe it will be in the next C standard. For now, you can take a look at Blocks, a non-standard extension added by Apple. This is an example code from Wikipedia:
#include <stdio.h>
#include <Block.h>
typedef int (^IntBlock)();
IntBlock MakeCounter(int start, int increment) {
__block int i = start;
return Block_copy( ^ {
int ret = i;
i += increment;
return ret;
});
}
int main(void) {
IntBlock mycounter = MakeCounter(5, 2);
printf("First call: %d\n", mycounter());
printf("Second call: %d\n", mycounter());
printf("Third call: %d\n", mycounter());
/* because it was copied, it must also be released */
Block_release(mycounter);
return 0;
}
/* Output:
First call: 5
Second call: 7
Third call: 9
*/
C is intended to be a small and simple language. It deliberately omits high-level features when the same things can be done by simpler means. It aims to provide only the basic features that are absolutely necessary for portable programming.
C doesn't have references because they are just pointers. C doesn't have classes, inheritance and virtual functions, because you can just use structs and make vtables yourself using function pointers. It doesn't have a garbage collector because programmers can keep track of memory allocations themselves, it doesn't have templates because they are in fact just macros. If you need exceptions you can use longjmp, and instead of namespaces you simply add prefixes to names.
Adding any of these high-level shortcuts might make programming a little more comfortable, but this comes at the cost of making the language more complicated, which must not be underestimated. It is a slippery slope that directly leads to the mess that C++ has become.
C doesn't have lambda functions because they are not really necessary. Instead you can just use a static function and put the context in a struct.
2016 update: Apple-style lambdas with closures were once again presented to the Working Group at the London 2016 meeting, in a new proposal document that tries to address several of the failings of the previous attempt, tidying up the terminology and explanations and going into much more detail on how closures and lambdas can be made "C-like".
Since the reception was cautiously positive (7-0-9 Yes/No/Abstain), it's looking very possible that something similar to this will make it into the language soon.
The short answer is simply that C doesn't include lambda functions because nobody has yet made an acceptable proposal to the ISO C working group to include lambda functions.
You can take a look at a list of some of the proposals discussed by the working group here: http://www.open-std.org/jtc1/sc22/wg14/www/documents
The only proposal for lambdas of any kind that I can find in that list are Apple's blocks (as demonstrated in Yu Hao's answer), in document N1451. That proposal is discussed further in N1483, which compares it to C++ lambdas, and N1493 and N1542 which are the minutes of the meetings where those documents were presented.
There were several reasons why the proposal in N1451 couldn't be accepted, given in N1542:
- initially the committee had difficulty understanding the proposal
- it uses incorrect citations and terminology which contradicts the existing C standard
- it is apparently vague and incomplete
- Apple was in the process of trying to patent the feature (not clear if this is an obstacle to standardisation or not but I would assume so)
- A completely new feature with completely new semantics proposed in 2010 had precisely zero chance of being ready in time for 2011, and would have held up the release of C11
- Blocks as presented are not compatible with C++11 lambdas
It also looks like they were unconvinced that it was currently demonstrating enough utility. C standardisation apparently tries to be very conservative, and with only one major compiler implementing the feature it's likely that they would want to wait and see how it competes with C++ lambdas, and whether anybody else picks it up. It's not really a "C" feature as opposed to a "Clang" feature until multiple compilers are offering it.
All that said, the committee's votes did apparently lean very slightly in favour of the feature (6-5-4 Yes/No/Abstain), but not enough for the necessary consensus to include it.
As far as I can tell, the other big one, C++11 lambdas, have not been proposed for inclusion into C by anybody; and if you don't ask you don't get.
Any proposal for lambdas in C would add a whole slew of new rules about variable lifetimes and locations and copying and allocation and... etc. For a lot of people this potentially starts to look very un-C-like, with values getting moved around behind the programmer's back or having sudden unexpected changes in their lifespan - avoiding this sort of thing is half the reason people choose to write in C nowadays. So there also has to be a proposal that actually falls in line with C's "philosophy" before it can be taken seriously. I'm sure this can be done, but both of the big proposals so far have been designed for languages with a very different "philosophy" where this sort of thing is less of an obstacle, and don't necessarily reflect C's purpose and character as they currently stand.