(define (make-account balance password) (define (withdraw amount) (if (>= balance amount) (begin (set! balance (- balance amount)) balance) "Insufficient funds")) (define (deposit amount) (set! balance (+ balance amount)) balance) (define (make-authenticate correct-password) (lambda (credential) (if (not (eq? credential correct-password)) (error "Incorrect password")))) (define (make-dispatch correct-password) (define authenticate (make-authenticate correct-password)) (define (dispatch credential m) (authenticate credential) (cond ((eq? m 'withdraw) withdraw) ((eq? m 'deposit) deposit) ((eq? m 'make-joint) make-dispatch) (else (error "Unknown request -- MAKE-ACCOUNT" m)))) dispatch) (make-dispatch password)) (define (make-joint account password new-password) ((account password 'make-joint) new-password)) ; 1 ]=> (define peter-acc (make-account 100 'open-sesame)) ; ; ;Value: peter-acc ; ; 1 ]=> ((peter-acc 'open-sesame 'deposit) 15) ; ; ;Value: 115 ; ; 1 ]=> ((peter-acc 'open-sesame 'withdraw) 5) ; ; ;Value: 110 ; ; 1 ]=> ((peter-acc 'invalid-password 'withdraw) 5) ; ; ;Incorrect password ; ;To continue, call RESTART with an option number: ; ; (RESTART 1) => Return to read-eval-print level 1. ; ; 2 error> (restart 1) ; ; ;Abort! ; ; 1 ]=> (define paul-acc (make-joint peter-acc 'open-sesame 'rosebud)) ; ; ;Value: paul-acc ; ; 1 ]=> ((paul-acc 'rosebud 'withdraw) 20) ; ; ;Value: 90 ; ; 1 ]=> ((peter-acc 'open-sesame 'withdraw) 5) ; ; ;Value: 85 ; ; 1 ]=> ((peter-acc 'rosebud 'widthdraw) 10) ; cannot use the other person's password ; ; ;Incorrect password ; ; 1 ]=> ((paul-acc 'open-sesame 'withdraw) 10) ; cannot use the other person's password ; ; ;Incorrect password ; ; 1 ]=> ((paul-acc 'rosebud 'deposit) 100) ; ; ;Value: 185