views:

449

answers:

2

Say I have a pointer to a function _stack_push(stack* stk, void* el). I want to be able to call curry(_stack_push, my_stack) and get back a function that just takes void* el. I couldn't think of a way to do it, since C doesn't allow runtime function definition, but I know there are far cleverer people than me here :). Any ideas?

+7  A: 

I found a paper by Laurent Dami that discusses currying in C/C++/Objective-C:

More Functional Reusability in C/C++/Objective-c with Curried Functions

Of interest to how it is implemented in C:

Our current implementation uses existing C constructs to add the currying mechanism. This was much easier to do than modifying the compiler, and is sufficient to prove the interest of currying. This approach has two drawbacks, however. First, curried functions cannot be type-checked, and therefore require careful use in order to avoid errors. Second, the curry function cannot know the size of its arguments, and counts them as if they were all of the size of an integer.

The paper does not contain an implementation of curry(), but you can imagine how it is implemented using function pointers and variadic functions.

Jared Oberhaus
Looks like a good read, thanks!
Burke
+1 great find, and I like "Although we did not run extensive tests, we can estimate a curried function call to be approximately 60 times slower than a normal function call."
Thomas L Holaday
(I like it because sometimes you need something very badly, and a solution that runs only 60 times slower is infinitely better than no solution at all.)
Thomas L Holaday
Thanks, I found the link on the Wikipedia page "Currying": http://en.wikipedia.org/wiki/Curried_function
Jared Oberhaus
+2  A: 

Here's my first guess off the top of my head (may not be the best solution).

The curry function could allocate some memory off the heap, and put the parameter values into that heap-allocated memory. The trick is then for the returned function to know that it's supposed to read its parameters from that heap-allocated memory. If there's only one instance of the returned function, then a pointer to those parameters can be stored in a singleton/global. Otherwise if there's more than one instance of the returned function, then I think that curry needs to create each instance of the returned function in the heap-allocated memory (by writing opcodes like "get that pointer to the parameters", "push the parameters", and "invoke that other function" into the heap-allocated memory). In that case you need to beware whether allocated memory is executable, and maybe (I don't know) even be afraid of anti-virus programs.

ChrisW