# DRY Function Pointers in C

Just a quick post today about C function pointers. Over the past two years I have seen the occasional function pointer introduction post on Hacker News, but I rarely see this one weird trick.

The most recent I have read was this one by Dennis Kubes. I haven’t hung out with C for a while (I more frequently visit its octopussier cousin, onto which a lambda-shaped leg has been nailed), so the post triggered some fond memories.

This post is just a leg nailed to his post, so go read it now if you would like to know about function pointers in C.

Kubes presents an example where he defines a domath function, that accepts a pointer to a function that performs an operation on two integers:

int domath(int (*mathop)(int, int), int x, int y) {
return (*mathop)(x, y);
}


For a more realistic example, let’s say you implemented fold instead, and hey, why not left-fold also?

int fold_right(int (*f)(int, int), int init, const int * first, const int * last) {
int result = init;
while(first != last) {
result = f(result, *first++);
}
return result;
}

int fold_left(int (*f)(int, int), int init, const int * first, const int * last) {
int result = init;
while(first != last) {
result = f(*last--, result);
}
return result;
}


Now imagine a whole family of higher order functions like these… the two function signatures here are bad enough already. The syntax doesn’t communicate well – you actually have to work out wtf int (*f)(int, int) means, unless you write C in your sleep. Even then, there is a chance the next person to maintain your code will cry.

Let’s look out for our fellow coder and DRY those tears. C has syntax for typedefing function pointers. The result is much friendlier:

typedef int (*binary_int_op) (int, int);

int fold_right(binary_int_op f, int init, const int * first, const int * last) {
int result = init;
while(first != last) {
result = f(result, *first++);
}
return result;
}

int fold_left(binary_int_op f, int init, const int * first, const int * last) {
int result = init;
while(first != last) {
result = f(*last--, result);
}
return result;
}


That is still some weird ass syntax at first, but you write that once (per type/intent of function pointer) and then live a happier life. And if you choose the name intelligently, you can communicate the intent as fast as the reader can read English.

Or you could ditch C and use C++’s functional programming tools.