Enlico
Enlico

Reputation: 28490

What's the relevance of make-register accepting an argument (the name of the register) at all?

In §5.2.1, the following function is presented for creating a register

(define (make-register name)
  (let ((contents '*unassigned*))
    (define (dispatch message)
      (cond ((eq? message 'get) contents)
            ((eq? message 'set)
             (lambda (value) (set! contents value)))
            (else
             (error "Unknown request -- REGISTER" message))))
    dispatch))

However, the parameter nome is nowhere used in the body, so it's basically swallowed and ignored by the function. Therefore, what's the relevance of it?

Indeed, it's later used like this

(define (make-new-machine)
  (let ((pc (make-register 'pc))
        (flag (make-register 'flag))
        (stack (make-stack))
; ...

but would there be any difference if we had omitted that name paramter in the first place and used make-register like this?

(define (make-new-machine)
  (let ((pc (make-register))
        (flag (make-register))
        (stack (make-stack))
; ...

or am I missing something?

Upvotes: 1

Views: 39

Answers (1)

chrslg
chrslg

Reputation: 13491

I'd say no, it wouldn't make any difference.

Scheme might have some complex behaviour (the one used here being one, for people used to most other language: functions carry their context, and "stack" is not linear. So even tho make-register call, and more over the let inside it, are finished, since the returned dispatch still refers to the local context built by that let, so, that instance of variable contents continues to exist), it is also quite "pure". There isn't any mysterious side effects. So, your reasoning seems correct: that name serves no purpose.

My bet is that this is related to the exercises following in the same page: reader are asked to modify make-register to trace modifications of the register (display name of the register, old value and new value). And for that, of course, you need the name of the register to be at hand

Like this

(define (make-register name)
  (let ((contents '*unassigned*) (trace #f))
    (define (dispatch message)
      (cond ((eq? message 'get) contents)
            ((eq? message 'set)
             (lambda (value) 
                (if trace (display `(register ,name ":" ,contents "→" ,value)))
                (set! contents value)))
            ((eq? message 'trace-on) (set! trace #t))
            ((eq? message 'trace-off) (set! trace #f))
            (else
             (error "Unknown request -- REGISTER" message))))
    dispatch))

Demo:

> (define xx (make-register 'foo))
#<unspecified>
> ((xx 'set) 12)
#<unspecified>
> (xx 'trace-on)
#<unspecified>
> ((xx 'set) 15)
(register foo : 12 → 15)#<unspecified>
> (xx 'get)
15

So, my code just added the (if trace...) line, plus the messages to change trace. But the name of the register was already there. I bet this is because this kind of modification was expected that that name is there. Or, more pragmatically, that whoever wrote those exercise, as any teacher would do, wrote first the complete solution, and the remove some part to create the partial code given to students, and forgot to remove the name :D

Upvotes: 1

Related Questions