[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

RE: accumulator generator (C++)



> (define (foo n)
>   (lambda (i) (set! n (+ n i)) n))

Having recently fortified the inner linings of my arteries with an
insulating layer of animal fat, I am now ready to tackle this in C++.

The plain C++ approach, as in Java, would also be to use a class, although
C++ supports extra sugar in its ability to overload the function call
operator, "()":

	class foo {
		int n;
	public:
		foo( int m ) { n = m; }
		int operator()( int i ) { n += i; return n; }
	};

This would be invoked as:

	foo f(4);
	f(3);
	f(2);

This can be jazzed up a bit with templates, e.g. to support incrementing of
arbitrary data types, rather than just "int":

	template <class T>
	class foo {
		T n;
	public:
		foo(T m) { n = m; }
		T operator()(T t) { return n += t; }
	};

Invoked as:

	foo<float> f(3.7);
	f(4.1);
	f(2.6)

But that's still a bit boring.  Instead, let's simulate lambda more
directly, as described here:
http://pobox.com/~oleg/ftp/c++-digest/Lambda-CPP-more.html

Using the "Lambda" definition on the above page, the problem can be
implemented as:

	typedef Lambda((int i), int n; int, return n+=i) foo;
	foo gen(int n) { foo f; f.n=n; return f; }

This is invoked with:

	foo f = gen(4);
	f(3);
	f(2);

For completeness, the required (general) definitions are:

#define XY(X,Y) X##Y
#define MakeNameXY(FX,LINE) XY(FX,LINE)
#define MakeName(FX) MakeNameXY(FX,__LINE__)
#define Lambda(args,ret_type,body) \
class MakeName(__Lambda___) { \
public: ret_type operator() args { body; } }

So one could claim that it takes 6 lines to implement "lambda" in C++.
<troll>Who's powerful now?</troll>

Of course, in the last example, I've regressed to using the "int" type
explicitly.  Fixing that is left as an exercise for the reader...

Anton