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 typedef
ing 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.
The post DRY Function Pointers in C appeared first on Alex Bowe.