Search code examples
schemesicp

SICP Ch. 3.1/ 3.2: Assigning a variable an object's parametric value


(Context: Ch. 3.1/3.2 SICP). Below is a simple 'counter' object. In normal code, of course you would get rid of v and replace it with initial-value in the count procedure. But experimenting, I noticed that v isn't affected by set! Why it this? I've only just started with the environmental model for procedures, but I can't make much sense of this behaviour.

(define (make-counter initial-value)

  (define v initial-value) ; is not affected by set! Why? 

  (define count
    (lambda () (begin (set! initial-value (+ v 1))
              v)))

  (define (dispatch m)
    (cond ((eq? m 'count) (count))))

  dispatch)

(define A1 (make-counter 0))

(A1 'count) ---> 0 ; expected ---> 0
(A1 'count) ---> 0 ; expected ---> 1

Solution

  • It's not working because initial-value is just a parameter that indicates the initial value of the counter. The value that you need to set is v, which holds the current counter value, like this:

    (define (make-counter initial-value)
      (define v initial-value)
      (define (count)
        (define prev v)
        (set! v (+ v 1))
        prev)
      (define (dispatch m)
        (cond ((eq? m 'count) (count))))
      dispatch)
    

    Now it works as expected:

    (define A1 (make-counter 0))
    (A1 'count)
    => 0
    (A1 'count)
    => 1