🚀 go-pugleaf

RetroBBS NetNews Server

Inspired by RockSolid Light RIP Retro Guy

Article View: comp.lang.misc
Article #2545

Re: Look, Ma, I can dynamically compose functions in C!

#2545
From: Bjarne Stroustrup
Date: Sun, 23 Dec 1990 14:59
143 lines
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!bs
References: <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