SICP Exercise 3.7

Question

Consider the bank account objects created by make-account, with the password modification described in Exercise 3.3. Suppose that our banking system requires the ability to make joint accounts. Define a procedure make-joint that accomplishes this. Make-joint should take three arguments. The first is a password-protected account. The second argument must match the password with which the account was defined in order for the make-joint operation to proceed. The third argument is a new password. Make-joint is to create an additional access to the original account using the new password. For example, if peter-acc is a bank account with password open-sesame, then

(define paul-acc
  (make-joint peter-acc
              'open-sesame
              'rosebud))

will allow one to make transactions on peter-acc using the name paul-acc and the password rosebud. You may wish to modify your solution to Exercise 3.3 to accommodate this new feature.

Answer

We can use the already defined withdraw and deposit functions and design dispatch in the same way we did for make-account.

(define (make-joint acc acc-pw password)
  (define (withdraw amount)
    ((acc acc-pw 'withdraw) amount))
  (define (deposit amount)
    ((acc acc-pw 'deposit) amount))
  (define (dispatch pw m)
    (cond ((eq? pw password)
           (cond ((eq? m 'withdraw) withdraw)
                 ((eq? m 'deposit) deposit)
                 (else (error "Unknown request:
                 MAKE-JOINT" m))))
          (else (error "Incorrect password"))))
  dispatch)

Let’s test it:

(define peter-acc (make-account 100 'open-sesame))

(define paul-acc
  (make-joint peter-acc
              'open-sesame
              'rosebud))

((paul-acc 'rosebud 'withdraw) 50)

And the result is just as expected:

50