Article View: comp.lang.misc
Article #2545Re: Look, Ma, I can dynamically compose functions in C!
From: Bjarne Stroustrup
Date: Sun, 23 Dec 1990 14:59
Date: Sun, 23 Dec 1990 14:59
143 lines
3688 bytes
3688 bytes
augustss@cs.chalmers.se (Lennart Augustsson @ Dept. of CS, Chalmers, Sweden)
writes
> I repeat what I was saying, you cannot write a function
> int (*compose)(f, g)
> int (*f)();
> int (*g)();
>
> so that it can be used by
>
> (*compose(ff, gg))(x)
>
> I did not claim that you cannot represent functions with some
> suitable datastructures (which you have shown). Of course you
> can do what ever computable thing you want in C, but sometimes
> you have to add a some extra stuff to represent what you want.
> There is nothing strange about that since a language cannot
> contain everything.
> I still make my old claim!
I know that C++ isn't (just) C and I know that trickery with
an auxuilerary type is necessary, but 'tis is the season for
some silliness so here is a solution in C++;
First the main function showing the programming style that can
be achieved:
main()
{
int i1 = g(1); // g writes "Merry "
// (and triples its argument)
int i2 = f(i1); // f writes "Christmas\n"
// (and doubles its argument)
int i3 = (f+g)(1);
fct h = f+g;
int i4 = h(1);
cout << i1 << '\n'
<< i2 << '\n'
<< i3 << '\n'
<< i4 << '\n';
}
and the output
Merry Christmas
Merry Christmas
Merry Christmas
3
6
6
6
Now the scaffolding:
typedef int (*PFI)(int);
class fct {
// if f is a fct f() calls all functions in f
// and (f+g)(i) means f(g(i))
PFI* p;
int sz; // size of allocation
int n; // number of contained functions
public:
fct& operator+=(const fct&);
fct& operator+=(PFI);
friend fct operator+(const fct&,const fct&);
friend fct operator+(const fct&,PFI);
friend fct operator+(PFI,const fct&);
int operator()(int);
fct(PFI f) : sz(10), n(1), p(new PFI[10]) { p[0] = f; p[1] = 0; }
fct(const fct&);
fct& operator=(const fct&);
~fct() { delete p; }
};
int fct::operator()(int a) // application operator
{
int t = a;
for (int i = n-1; i>=0; i--) t = p[i](t);
return t;
}
fct& fct::operator+=(const fct& a)
// add to list of contained functions
{
int nn = n+a.n;
if (nn>=sz) { // not enough space, double allocation
PFI* pp = new PFI[sz=sz+a.sz];
for (int i = 0; i<n; i++) pp[i] = p[i];
delete p;
p = pp;
}
for (int i = n; i<=nn; i++) p[i] = a.p[i-n]; // copy cc
n = nn;
return *this;
}
fct::fct(const fct& a) // make a copy
{
sz = a.sz;
n = a.n;
p = new PFI[sz];
for (int i = 0; i<=n; i++) p[i] = a.p[i];
}
fct operator+(const fct& c1, const fct& c2)
{
fct cc(c1);
return cc+=c2;
}
#include<stream.h>
int _f(int i) { cout<<"Christmas\n"; return i+i; }
int _g(int i) { cout<<"Merry "; return i+i+i; }
fct f(_f);
fct g(_g);
and the ``main program'' repeated in case you have forgotten it:
main()
{
int i1 = g(1);
int i2 = f(i1);
int i3 = (f+g)(1);
fct h = f+g;
int i4 = h(1);
cout << i1 << '\n'
<< i2 << '\n'
<< i3 << '\n'
<< i4 << '\n';
}
This example has not been extensively tested. I just wrote it,
compiled it and ran it.
Technical Details
Message-ID:
<11736@alice.att.com>Path:
arc1-ca.pugleaf.net!utzoo!attcan!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!thunder.mcrcim.mcgill.edu!snorkelwacker.mit.edu!usc!ucsd!pacbell.com!att!att!dptg!ulysses!andante!alice!bsReferences:
<20@garth.UUCP> <27534.276e5bd3@kuhub.cc.ukans.edu> <1990Dec22.001419.21222@mathrt0.math.chalmers.se>Show Full Headers
Complete Article Headers
Path: arc1-ca.pugleaf.net!utzoo!attcan!utgpu!news-server.csri.toronto.edu!clyde.concordia.ca!thunder.mcrcim.mcgill.edu!snorkelwacker.mit.edu!usc!ucsd!pacbell.com!att!att!dptg!ulysses!andante!alice!bs From: bs@alice.att.com (Bjarne Stroustrup) Newsgroups: comp.lang.misc Subject: Re: Look, Ma, I can dynamically compose functions in C! Summary: A C++ version, Merry Christmas! Message-ID: <11736@alice.att.com> Date: 23 Dec 90 14:59:36 GMT References: <20@garth.UUCP> <27534.276e5bd3@kuhub.cc.ukans.edu> <1990Dec22.001419.21222@mathrt0.math.chalmers.se> Organization: AT&T Bell Laboratories, Murray Hill NJ Lines: 143