Article View: comp.lang.functional
Article #817Re: function composition in C
From: John Lupien
Date: Fri, 01 Mar 1991 20:25
Date: Fri, 01 Mar 1991 20:25
107 lines
3691 bytes
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!lupienjReferences:
<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