In 1999, Raymond Wiker <
[email protected]> wrote or quoted:
Compare the following:
(defun f(a)
(cons
(lambda () (setq a (1+ a)))
(lambda () (setq a (+ a a)))))
(setq g (f 2))
(funcall (car g))
(funcall (car g))
(funcall (cdr g))
(funcall (cdr g))
(setq h (f 2))
(funcall (car h))
(funcall (car h))
(funcall (cdr h))
(funcall (cdr h))
with:
class F {
public:
friend class Car {
public:
Car (F& f) : a(F.a)
{}
int operator()()
{ return a++; }
private:
int& a;
}
friend class Cdr {
public:
Cdr(F& f) : a(F.a)
{}
int operator()()
{ return a*=2; }
private:
int& a;
}
F(aa) : a(aa), car(this), cdr(this)
{}
private:
int a;
Car car;
Cdr cdr;
};
main()
{
F g(2);
F h(2);
cout << g.car() << endl;
cout << g.car() << endl;
cout << g.cdr() << endl;
cout << g.cdr() << endl;
cout << h.car() << endl;
cout << h.car() << endl;
cout << h.cdr() << endl;
cout << h.cdr() << endl;
}
In the meantime, one can write closure in C++ too,
so it might make sense to update the C++ part.
#include <iostream>
#include <functional>
#include <memory>
/* A pair of functions operating on shared state */
struct FuncPair
{ ::std::function< void() > inc; /* like ( car g ) */
::std::function< void() > dbl; /* like ( cdr g ) */ };
/* Factory function f */
FuncPair f( int init )
{ auto a = ::std::make_shared< int >( init ); /* variable to enclose */
FuncPair fp
{ [ a ]() /* enclose "a" */
{ ++*a;
::std::cout << "inc: " << *a << '\n'; },
[ a ]() /* enclose "a" */
{ *a += *a;
::std::cout << "dbl: " << *a << '\n'; }};
return fp; }
int main()
{ auto g = f( 2 );
g.inc(); /* 3 */
g.inc(); /* 4 */
g.dbl(); /* 8 */
g.dbl(); /* 16 */
auto h = f( 2 );
h.inc(); /* 3 (fresh state, independent of g's) */
h.inc(); /* 4 */
h.dbl(); /* 8 */
h.dbl(); /* 16 */ }
--- SoupGate-Win32 v1.05
* Origin: fsxNet Usenet Gateway (21:1/5)