6 ms·
Lambdas in C
- Kototama 15y agoNote: unlike lambdas in functional languages, this lambda does not capture the containing environment.
- Jach 15y agoBah, beat me to it. It's still kind of cool though. qsort (array, sizeof (array) / sizeof (array[0]), sizeof (array[0]), lambda (int, (const void *a, const void *b), { dump (); printf ("Comparison %d: %d and %d\n", ++ comparison, *(const int *) a, *(const int *) b); return *(const int *) a - *(const int *) b; }));
- ori_b 15y agoThat's slightly sloppy phrasing. It captures it, but it does not duplicate it, so it's lifetime is tied to the stack frame of the function you declared it in. In short, you can only do downwards funargs.
- brohee 15y agoAm I really out of my mind or is this not a lambda at all but just an anonymous function?
- StrawberryFrog 15y agoIf an anonymous function can capture state from the enclosing code block, and outlive that code block, then it's a lambda. So this probably isn't really a lambda.
- philwelch 15y agoThat's the definition of a closure. I'm not sure if "lambda" is necessarily synonymous with "closure" or just synonymous with "anonymous function", but lambdas are closures in many languages.
- StrawberryFrog 15y agoYou're right, my terms are sloppy. Are there rigorous definitions, or does it vary between languages?. I think of "lambda" as a language construct that creates closures. "anonymous functions" are of course just a simpler subset of closures.
- jensnockert 15y agoBlocks, http://clang.llvm.org/docs/BlockLanguageSpec.txt http://clang.llvm.org/docs/BlockLanguageSpec.txt Much better solution to the problem, hopefully coming to standard GCC soon(tm).
- Rexxar 15y agoThey should try to make something syntactically compatible with C++ lambdas. It's annoying that the two languages are more and more incompatible for cosmetic reasons.
- eps 15y agoIn other words - he discovered gcc's ({ }) construct and decided to write a macros named lambda around it. http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC62 http://gcc.gnu.org/onlinedocs/gcc-2.95.3/gcc_4.html#SEC62
- deleted 15y ago[deleted]
- ori_b 15y agoYou're not passing a compound statement expression as a function pointer. You are passing the result of the evaluation of that expression --which is a function pointer -- as a function pointer.
- tjr 15y agoOops, sorry, I just deleted my comment because I thought that wingo's comment covered my thoughts and more. For posterity, I had previously written: I do not find it obvious from that documentation that you can pass a compound statement expression as a function pointer. And touche', I just glanced at the contents of the macro before replying.
- wingo 15y agoTo me it's a bit more surprising: it's a statement expression, containing a nested function, then we take the address of that nested function. Having that series of operations produce something useful is unexpected, to say the least. It's nothing I'd want to see in code that I maintain, but I think you have to give it a bit more credit. Besides that, it's cute :)
- tjr 15y agoAny idea if this is now officially supported in GCC? The blog post is from nearly a year ago.
- 15y ago
- demallien 15y agoprintf("I am bad and evil %p\n", ({int bad_and_evil(void){return 0;};&bad_and_evil;})); printf("I am bad and evil2 %d\n", ({0x4FFFFFF;})); void* result = ({void* bad_and_evil(int dummy){return 0;};&bad_and_evil;}); printf("bad and evil 3 = %p\n", result); * shudder * Getting a return value from a block, by inserting it in parantheses.
- chrisjsmith 15y agoIsn't this a step closer to Greenspuns Tenth Rule? "Any sufficiently complicated C or Fortran program contains an ad-hoc, informally-specified, bug-ridden, slow implementation of half of CommonLisp" (bar the environment/scope issue it avoids that is)
- jpr 15y agoMore accurate title would be "Something like, but not as useful or generic as, lambdas in gcc's dialect of C".
- madmoose 15y agoOne might say, to paraphrase Douglas Adams, that it's almost, but not quite, entirely unlike lambdas.
- snorkel 15y agoCute, but functions pointers suit me just fine.
- huhtenberg 15y agoAnonymous functions are very handy, and I think they should really be taken a step further. There's really no reason why it shouldn't be possible to pass an actual function body where a function pointer is required: int v[...]; qsort( v, ..., (a, b) { return *(int*)a - *(int*)b } ); Such usage would also have an added benefit of letting the compiler do the type inference for a, b and the return value and not needing to explicitly specify them in qsort() call.
- CamperBob 15y agoLocal functions would be a nice compromise between the unreadable glop that was posted and the need to declare an entirely separate function to execute localized actions.
- juiceandjuice 15y agoThis is just too clumsy, and this is exactly why I think go will take off. package main import "fmt" func main() { add := func(x int, y int) int{ return x+y } max := func(x int, y int) int{ if x>y {return x} return y } fmt.Printf("lambda: add:%d\n",add(2,3)) fmt.Printf("lambda: max:%d\n",max(2,3)) } Although it'd be nice if you could have a ternary or something like return {x} if x>y else {y}
- juiceandjuice 15y agoalso, this works too: val := func(x int, y int) int{return x+y}(2,4)
- huhtenberg 15y agoNice, but how is this useful though?
- gok 15y agoIs that really that much better than C blocks? #include <stdio.h> int main (int argc, char const *argv[]) { int (^add)(int, int) = ^(int x, int y) { return x + y; }; int (^max)(int, int) = ^(int x, int y) { return (x > y) ? x : y; }; printf("block: add:%d\n", add(2,3)); printf("block: max:%d\n", max(2,3)); return 0; }
- juiceandjuice 15y agoI personally think so, as I think blocks in C are a clumsy way around the issue (probably because C doesn't natively have garbage collection) and it feels natural in go, but I know others will disagree. Also, I don't think you can make it anonymous, can you? func(x int, y int){fmt.Printf("%d\n",x+y)}(2,4)
- gok 15y agoYou sure can. ^(int x, int y){printf("%d\n",x+y);}(2,4); Automatic memory management is interesting, but orthogonal.
- athom 15y agoMy favorite part: l_anonymous_functions_name Sorry, I just like the irony.
- CPlatypus 15y agoIf I worked on static code analysis tools for a living, this would make me cry.
- wbhart 15y agoI have not been able to work out two things here: 1) If I define a lambda inside a function, I cannot return the lambda from the function and use it right? 2) Recursive lambdas are not possible on account of the lack of recursion in C macros (not sure if that even makes sense without 1).