It would be more useful to package the counter variable with the procedure that manipulates it. Then we could create as many counters as we want, each with its own counter variable to manipulate.
The Stateful Application Rule (from Section 9.2.2) suggests a way to do this: evaluating an application creates a new environment, so a counter variable defined an the application environment is only visible through body of the created procedure.
make-counter procedure creates a counter object that packages the
count variable with the procedure that increases its value:
(lambda () (set! count (+ 1 count)) count))
Each application of
make-counter produces a new object that is a procedure with its own associated
count variable. Protecting state so it can only be manipulated in controlled ways is known as encapsulation.
count place is encapsulated within the counter object. Whereas the previous counter used the global environment to store the counter in a way that could be manipulated by other expressions, this version encapsulates the counter variable so the only way to manipulate the counter value is through the counter object.
make-counter definition uses a let expression to make the initialization of the
count variable clearer:
(let ((count 0))
(lambda () (set! count (+ 1 count)) count)))
Figure 10.1 depicts the environment after creating two counter objects and applying one of them.