• Re: Newbie questions

    From ram@ram@zedat.fu-berlin.de (Stefan Ram) to comp.lang.lisp on Sun Aug 31 18:56:33 2025
    From Newsgroup: comp.lang.lisp

    In 1999, Raymond Wiker <raymond@orion.no> 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 */ }


    --- Synchronet 3.21a-Linux NewsLink 1.2