On Wed, Sep 14, 2011 at 08:02:33PM -0700, Steve Graham wrote:
On a final note, I am mystified as to how the code works. This is an example of it being defined and run on my Windows 7x64 machine:
Gambit v4.6.1
(define (counter)
(let ((value 0)) (lambda () (set! value (+ value 1)) value)))
(define first-counter (counter)) (first-counter)
1
(first-counter)
2
(first-counter)
3
(first-counter)
4
It seems to initialize value to 0 and I assume that happens the first time you use (counter) to define another form. What I don't understand is why the code for initializing is skipped every time (first-counter) is run.
To be clear: the identifier "first-counter" is bound to a procedure, defined by lambda statement. The lambda captures the initial value of "counter" when it is defined. But when you call (first-counter), it's not going through the codepath that includes the let statement. It's just executing the lambda code, which has captured the state of "counter", and that state persists as long as its enclosing lambda does (the lambda "closes over" counter; that's why it's called a "closure").
You can think of counter as a private data member in an OO Algol language.
-Joe