🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.functional
Article #817

Re: function composition in C

#817
From: John Lupien
Date: Fri, 01 Mar 1991 20:25
107 lines
3691 bytes
In article <6316@rex.cs.tulane.edu> fs@caesar.cs.tulane.edu (Frank Silbermann) writes:
>In article <6873@munnari.oz.au> aet@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.
>>	A call should look something like this:
>>		(compose(sqr,cube)) (2)
>>	which would evaluate to 64.
>Compose would input two functions, and return a _new_ function.
>This is impossible to do _directly_ in C,
>as all functions must created at compile time.
>>	Feel free to use pointers wherever they seem appropriate.
>>	(so the above call could look like:
>>	(*compose(&sqr,&cube)) (2)	   )
>I suggest you let `compose' take _three_ parameters,
>the two functions and also the argument upon which the
>result is to be applied, so the call would look like:
>compose(&sqr,&cube, 2).

This is OK, but the "compose" function should be able to take
any number of function pointer arguments directly.

>Alternatively, you could name a new _datatype_ `composition',
>which is _implemented_ as a record of two function pointers
>(comp.first and comp.second).  To create compositions,
>you could write a function `compose' that inputs two function pointers
>and returns them embedded in a single record of type `composition'.
>To apply compositions, you write a function `apply' that inputs
>a composition X and an argument Y, and returns:  *x.second(*x.first(Y)).

This is the data-structure driven (and probably most portable) way to
go about it. However, if you put the data argument first,  any machine
with a C compiler and library that supports "varargs(5)" (which is the
"portable" variable number of arguments support package) can be used to
write a "compose" function that takes a data value (of fixed type),
iteratively apply each of a list of function pointers to it, and return the
result. 

Here's an example for "double" data. The argument list must be terminated
with a null pointer in this implementation, but an integer count of functions
to be applied could be supplied as the second argument instead.

/* start of file dbl_compose.c */

#include <varargs.h>
#include <stdio.h>

double dbl_compose();
double sqare();
double cub();
double halve();

void
main()
{
	double foo;
	foo = dbl_compose(2.0, sqare, cub, halve, (double (*)())NULL);
	printf("result is %f\n",foo);
}

double
dbl_compose(va_alist)
va_dcl					/* note lack of semi-colon */
{
	va_list ap;			/* arg list scanner */
	double result;
	double (*func)();		/* function pointer */
	va_start(ap);			/* initialize the arglist scanner */
	result = va_arg(ap,double);	/* read off the data arg */
	while(1)
	{
		func = (double (*)())(void *)va_arg(ap,char *);
		if (func == ((double (*)())NULL))
		{
			break;
		}
		result = (*func)(result);
	}
	va_end(ap);
	return(result);
}

double
sqare(foo)
double foo;
{
	return(foo * foo);
}

double
cub(foo)
double foo;
{
	return(foo * foo * foo);
}

double
halve(foo)
double foo;
{
	return(foo/2);
}

/* end of file dbl_compose.c */

---
John R. Lupien
lupienj@hpwarq.hp.com
Technical Details
Message-ID: <1764@hpwala.wal.hp.com>
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!lll-winken!elroy.jpl.nasa.gov!sdd.hp.com!hplabs!hpda!hpwala!hpwadac!lupienj
References: <6873@munnari.oz.au> <6316@rex.cs.tulane.edu>

Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!sun-barr!lll-winken!elroy.jpl.nasa.gov!sdd.hp.com!hplabs!hpda!hpwala!hpwadac!lupienj
From: lupienj@hpwadac.hp.com (John Lupien)
Newsgroups: comp.lang.functional
Subject: Re: function composition in C
Message-ID: <1764@hpwala.wal.hp.com>
Date: 1 Mar 91 20:25:00 GMT
References: <6873@munnari.oz.au> <6316@rex.cs.tulane.edu>
Sender: netnews@hpwala.wal.hp.com
Reply-To: lupienj@hpwadac.UUCP (John Lupien)
Organization: Hewlett Packard, Waltham, Mass
Lines: 107