function composition in C

Anurag Acharya acha at CS.CMU.EDU
Fri Mar 1 04:05:57 AEST 1991


In article <ACHA.91Feb28002548 at DRAVIDO.CS.CMU.EDU> acha at CS.CMU.EDU (Anurag Acharya) writes:
> In article <6873 at munnari.oz.au> aet at felix.ee.mu.OZ.AU (bert) writes:
> > Does anyone know how to write a compose function in C,
> > without writing a Scheme interpreter to do it in.
> Nope. it is possible.

As Brad White points out my solution used a compose function whose type was
((int->int) x (int->int) x int)->int whereas the original question asked for
a compose function that had the type (int->int) x (int->int) -> (int->int)

In this note contains two other solutions. The compose function in the first 
one looks and feels the same a compose functional in a functional language
except that susbequent calls to compose may alter the behaviour of the 
function returned by compose. The second solution doesnot have this problem
but requires an explicit "apply" operation. It pretty much does what 
functional languages do for composition -- create a closure at composition
and use the info during application.
The explicit apply operation is needed because unlike Scheme, SML etc., C's
nested lexical scopes cannot contain function declarations.

anurag

------------------------------------------------------------------------------
First Solution:

#include <stdio.h>

typedef int (*fptr)();

static int (*foo)(), (*bar)();

int compose1 (baz)
int baz;
{
   return ((*foo) ((*bar)(baz)));
 }

fptr compose(f,g)
fptr f;
fptr g;
{
  foo = f; bar = g;
  return compose1;
}

int sqr(x)
int x;
{
 return x * x;
}

int cube(x)
int x;
{
 return x * x * x;
}

main()
{
  printf("The value is %d\n",compose(sqr,cube)(2) );
}

-------------------------------------------------------------------------------
Second solution:

#include <stdio.h>


typedef int (*fptr)();

typedef struct CLOS
{
  fptr foo;
  fptr bar;
} closure;

closure *compose(f,g)
fptr f;
fptr g;
{
  closure *tmp;

  tmp = (closure *) malloc(sizeof(closure));
  tmp->foo = f;
  tmp->bar = g;
}

int apply (clos,arg)
closure *clos;
int arg;
{
   return((*(clos->foo))((*(clos->bar))(arg)));
 }

int sqr(x)
int x;
{
 return x * x;
}

int cube(x)
int x;
{
 return x * x * x;
}

int quad(x)
int x;
{
 return x * x * x * x;
}

main()
{
 closure *a, *b;
 a = compose(sqr,cube);
 b = compose(sqr,quad);

  printf("sqr(cube 2) is %d\n",apply(a,2) );
  printf("sqr(quad 2) is %d\n",apply(b,2) );
  printf("sqr(cube 3) is %d\n",apply(a,3) );
}



More information about the Comp.lang.c mailing list