MT3 Review Solution: -- OOP Modifications are in ALLCAPS. (define-class (client name server) (instance-vars (latest-message '())) (initialize (ASK SERVER 'ACCEPT-CONNECTION SELF)) (method (receive-messages msg) (set! latest-message msg)) (method (send-message msg who) (ask server 'send-to-client msg who))) (define-class (server) (instance-vars (clients '())) (method (accept-connection client) (set! clients (cons client clients))) (method (send-to-client msg name) (ASK (CAR (FILTER (LAMBDA (CLIENT) (EQ? (ASK CLIENT 'NAME) NAME)) CLIENTS)) 'RECEIVE-MESSAGE MSG))) (define-class (broadcast-client name server) (parent (client name server)) (method (broadcast msg) (ask server 'broadcast msg))) (define-class (broadcast-server) (parent (server)) (method (accept-connection client) (USUAL 'ACCEPT-CONNECTION CLIENT) (ask self 'broadcast (cons (ask client 'name) '(has joined us)))) (method (broadcast msg) (for-each (lambda (c) (ask c 'receive-message msg)) (USUAL 'CLIENTS)))) -- Environment Diagram Use envdraw to verify -- List Mutations 1 - 3. Use envdraw to verify 4. The easiest way to do a problem like this is to use a LET in which you give names to every relevant piece of the list structure. Then, inside the LET, you can mutate the pairs in any old order without risk of error: (define (make-alist! lst) (if (null? lst) 'done (let ((car1 (car lst)) (cdr1 (cdr lst)) (car2 (cadr lst)) (cdr2 (cddr lst))) (set-car! lst cdr1) (set-cdr! lst cdr2) (set-car! cdr1 car1) (set-cdr! cdr1 car2) (make-alist! cdr2)))) But that's more work than is really needed. If you're clever about the order in which you do the mutation, you can get by with only one temporary variable. There are several such solutions; here's one: (define (make-alist! lst) (if (null? lst) 'done (let ((tmp (cddr lst))) (set-cdr! (cdr lst) (cadr lst)) (set-car! (cdr lst) (car lst)) (set-car! lst (cdr lst)) (set-cdr! lst tmp) (make-alist! tmp)))) 5. The question is slightly unclear. The following solution does not update the values of any variables that point to seq, but is much simpler than the second solution: (define (last-pair lst) (if (null? (cdr lst)) lst (last-pair (cdr lst)))) (define (nthcdr n lst) (if (= n 0) lst (nthcdr (- n 1) (cdr lst)))) (define (list-rotate! n lst) (if (= n 0) lst (let ((new-lst (nthcdr n lst))) (set-cdr! (nthcdr (- n 1) lst) '()) (set-cdr! (last-pair new-lst) lst) new-lst))) ----- This version rotates the values inside the cars of the pairs: (define (list-rotate! n seq) (define (one-round! l first-e) (if (null? (cdr l)) (set-car! l first-e) (begin (set-car! l (cadr l)) (one-round! (cdr l) first-e)))) (if (= n 0) seq (begin (one-round! seq (car seq)) (list-rotate! (- n 1) seq)))) Notice that the following code is wrong! (define (list-rotate! n seq) (if (= n 0) seq (begin (let ((end (last-pair seq)) (old-first seq) (new-first (cdr seq))) (set-cdr! end seq) (set-cdr! old-first ()) (list-rotate! (- n 1) new-first))))) (define (last-pair l) (if (null? (cdr l)) l (last-pair (cdr l)))) Since the original variable does not point to the beginning of the mutated list. It still points to the first pair in the original list. -- Vector 1. (define (vector-lookup key) (define (iter index) (cond ((< index 0) #f) ((eq? key (vector-ref v-keys index)) (vector-ref v-values index)) (else (iter (- index 1))))) (iter (- (vector-length v-keys) 1))) 2. (define (vector-swap! v i j) (let ((temp (vector-ref v i))) (vector-set! v i (vector-ref v j)) (vector-set! v j temp))) (define (vector-reverse! v) (define (iter i j) (if (>= i j) v (begin (vector-swap! v i j) (iter (+ i 1) (- j 1))))) (iter 0 (- (vector-length v) 1))) -- Concurrency 1. 100, -15, 45, -10, -5, -30, 25 2. a) Incorrect b) Neither c) Neither d) Neither e) Deadlock