The Wikipedia article on function types lists an interesting declaration of a "higher-order function composition function":
int (*compose(int (*f)(int), int (*g)(int)))(int);
As a learning exercise, I wanted to implement this in a test program, but failed, with the compiler throwing a number of warnings and errors. My attempt:
int a(int x) {
return x + 1;
}
int b(int x) {
return x * 2;
}
int (*compose(int (*f)(int y), int (*g)(int z)))(int x) {
return (*f)(x) - (*g)(x);
}
int main(void) {
int x = 5;
int r = (*compose)((*a)(x), (*b)(x))(x);
printf("Compose result for x = %d: %d\n", x, r);
return 0;
}
I would be grateful for an explanation of how the declaration from Wikipedia differs from a simple function composition like f(g(h(x)))
and how it may be implemented, preferrably with a simple program similar to mine.
Your compose
function is declared to return a function pointer, but calculates and returns an int
value instead.
Also (*a)(x)
calls the a
function and you pass the int
result to compose
, instead of a pointer to the function a
itself. Same with b
.
To solve your problem you first should call compose
with pointers to the functions a
and b
:
int r = (*compose(&a, &b))(x);
Then you need to make compose
return a pointer to a function, which includes creating the function to be returned:
int (*f1)(int);
int (*f2)(int);
int compose_helper(int x)
{
return f1(x) - f2(x);
}
int (*compose(int (*f1_)(int), int (*f2_)(int)))(int)
{
f1 = f1_;
f2 = f2_;
return &compose_helper;
}
In C there's really no nice way of doing this, as function composition can't be done at run-time and there needs to be global state.
As a side-note I really recommend that you create type-aliases for the function-pointers to make it all easier to read and understand.
As in
typedef int (fp_type)(int);
fp_type *f1;
fp_type *f2;
fp_type *compose(fp_type *f1_, fp_type *f2_) { ... }