


		MASSACHVSETTS INSTITVTE OF TECHNOLOGY
      Department of Electrical Engineering and Computer Science

      6.001 -- Structure and Interpretation of Computer Programs
		      Quiz 2   Fall Term   1993
			      Open Book


Print your name at the top of each page of this exam.

Please write clear and concise answers to the questions posed in the
spaces provided in this handout.  You may use scratch paper if you
wish, but the spaces provided for the answers are the ONLY places we
will look at when grading the quiz.  Your answers should be brief and
clear.  The staff reserves the right to ignore illegible answers.  In
grading problems that require programming, the staff will take into
consideration the STYLE and clarity of your code, not just whether it
happens to produce the right result.  Before starting, please check
that this booklet has all 8 pages (not counting this cover page).

Note that not all of the problems here involve the full complexity of
the handout.



Print your name here:_______________________________________________

Problem 0 (2 points):

A. Print your tutor's name here:_______________________________________


B. Recitation instructor:____________________________________________



If you have any comments about this quiz, please write them here:






       Please do not write below this line -- reserved for administrivia.
_______________________________________________________________________________

Problem  Grade   Grader         Grader's Comments
--------------------------
| 0    |      |         || 
--------------------------
| 1    |      |         ||
--------------------------
| 2    |      |         ||
--------------------------
| 3    |      |         ||
--------------------------------------------------
| 4    |      |         ||TOTAL |      |         |
--------------------------------------------------

 

Page 1 of 10.        Your Name:______________________________________

Problem 1. The following problem is a simplified version of one that was
assigned for tutorial as part of problem set 6.

Suppose that we evaluate the following sequence of definitions:

(define (make-flip)
  (let ((state 1))
    (lambda ()
      (if (= state 0)
          (set! state 1)
          (set! state 0))
      state)))

(define flip (make-flip))

(define flap1 (flip))

(define (flap2) (make-flip))

(define flap3 (flap2))

(define (flap4) (flip))

What is the value of each of the following expressions (evaluated in the
order shown).  If you think the expression evaluates to a procedure, then
write "procedure."  If you think that the evaluation will produce an error,
then indicate what the error would be.

flap1 ===> 

flap2 ===> 

flap1 ===>

(flap1) ===>

(flap2) ===>

(flap3) ===>

(flap4) ===>

(flap3) ===>


Page 2 of 10.






	   EXTRA COPY OF ENVIRONMENT DIAGRAM FOR PROBLEM 2





Page 3 of 10.        Your Name:______________________________________

Problem 2. The following sequence of commands will make a bank, an
account, and a depositor.  (The MAKE-BANK and MAKE-DEPOSITOR procedures
here refer to the procedures on pages 3 and 4 of the handout -- NOT
the ones that use the object system from PS6.)

(define bcci (make-bank 'bcci 100000000.00 .01 .005))

(define bcci1 ((bcci 'open-account) 'bcci1))

(define person1
  (make-depositor 'Michael-Milken 100000 200000 50000 1000
                  (list bcci1)))

Part A. The incomplete environment diagram shown below describes the
situation after these three definitions have been evaluated.  There are
eight pointers that are incomplete.  The stubs are labeled with a letter
and a question mark (A? through H?).  Such a pointer should point to a
labeled item in the diagram.  Procedures are labeled Pn, environment frames
are labeled En, and lists are labeled Ln (as in "P2" or "E3" or "L1").
Complete the diagram by extending the pointer stubs to the correct places.
Summarize your answers by completing the table at the bottom of the page.
ONLY THE TABLE WILL BE GRADED.  An extra copy of the environment diagram,
for scratch work, is given on the facing page.
































Your Answers:   A:______  B:______  C:______  D:______


                E:______  F:______  G:______  H:______

Page 4 of 10.

Problem 2 (continued).

Part B. Suppose we now execute 

              ((bcci1 'transact) 1000000 'donald-trump)

This will create some new environment frames.  One of these frames
will contain a binding for the variable MESSAGE.  To which of the
following frames will this frame point as its enclosing environment?
Circle the correct answer.


                        E1  E2  E3  E4  E5  E6


	
Part C. Suppose we make another account in the BCCI bank.  One of the
environment frames that used to have one frame pointing at it will now
have two frames pointing at it.  Which frame is this?  Circle the
correct answer.


                        E1  E2  E3  E4  E5  E6


Page 5 of 10


Page 6 of 10.        Your Name:______________________________________


		      CODE LISTING FOR PROBLEM 3


1     (define *the-banks* '())

2     (define (make-bank bank-name assets return-rate account-rate)
3       (let ((accounts '()))
4         (define (open-account account-name)
5           (let ((balance 0))
6             (define (get-balance)
7               balance)
8             (define (transact amount depositor-name)
9               (write-line
10                `(transaction ,bank-name ,account-name ,amount ,depositor-name))
11              (cond ((not (memq the-account accounts))
12                     'inactive-account)
13                    ((> (+ balance amount) 0)
14                     (set! balance (+ balance amount))
15                     (set! assets (+ assets amount))
16                     balance)
17                    (else 'insufficient-funds)))
18            (define (the-account message)
19              (cond ((eq? message 'transact) transact)
20                    ((eq? message 'get-balance) get-balance)
21                    (else (error "Unknown action -- ACCOUNT"))))
22            (set! accounts (cons the-account accounts))
23            the-account))
24        (define (compute-interest)
25          (set! assets (+ assets (* return-rate assets)))
26          (for-each (lambda (account)
27                      (let ((interest
28                              (* account-rate ((account 'get-balance)))))
29                        (set! assets (- assets interest))
30                        ((account 'transact) interest 'monthly-interest)))
31                    accounts)
32          assets)
33        (define (the-bank message)
34          (cond ((eq? message 'open-account) open-account)
35                ((eq? message 'compute-interest) compute-interest)
36                (else (error "Unknown message -- BANK"))))
37        (set! *the-banks* (cons the-bank *the-banks*))
38        the-bank))

Page 7 of 10.        Your Name:______________________________________

Problem 3. Suppose that we want to use our simple message-passing bank
(p.3 of the handout) in a parallel execution system, as in Problem Set 7.

On the facing page you will find the definition of MAKE-BANK from the
handout.  The lines are numbered for reference.

The code is full of bugs that may arise in concurrent execution.  One kind
of concurrent execution is if the depositors are allowed to perform
transactions concurrently.  More complex problems arise if new accounts may
be made or if new banks may be made concurrently with depositor activity.

Part A. Which of the following variables that occur in this code need to be
protected by serializers if the only concurrency is that the depositors are
allowed to perform transactions concurrently?  Circle the vulnerable
variables.

     *the-banks*  bank-name  assets  return-rate  account-rate

     accounts  account-name  balance  amount  depositor-name 

     message  account  interest


Part B. Which of the following variables that occur in this code need to be
protected by serializers if the depositors are allowed to execute
concurrently, and if new banks, new depositors and new accounts may be made
at any time?  Circle the vulnerable variables.

     *the-banks*  bank-name  assets  return-rate  account-rate

     accounts  account-name  balance  amount  depositor-name 

     message  account  interest


Page 8 of 10

Problem 3 (continued).

Part C. Suppose we want to protect the assignment to ACCOUNTS on line 22
using a serializer named ACCOUNTS-SERIALIZER, constructed by
(MAKE-SERIALIZER).  At which point in the code should the
ACCOUNTS-SERIALIZER be constructed?

  ___ Between lines 1 and 2

  ___ Included with the LET bindings in line 3

  ___ Between lines 8 and 9

  ___ Between lines 18 and 19

  ___ Between lines 21 and 22


In the space provided below, give a brief justification of your answer.








In the space provided below, write the replacement for line 22 needed to
protect the ACCOUNTS variable.







Part D. Suppose we do not protect any variables other than ACCOUNTS, as in
part C above.  In the space provided below, give an example illustrating
how concurrent depositor activity can lead to erroneous results.


Page 9 of 10.        Your Name:______________________________________

Problem 4

PART A. Louis Reasoner suggests that we could have simplified the
object-oriented code for MAKE-SLEAZY-BANK on page 9 of the handout by using
the variable ASSETS directly instead of calling (ASK SELF 'GET-ASSETS) and
(ASK SELF SET-ASSETS!).  Thus, he suggests that the MAKE-SLEAZY-BANK
procedure should be rewritten as follows.  (The changed lines are marked
with stars.)

(define (make-sleazy-bank bank-name assets return-rate account-rate)
  (let ((honest-bank (make-bank bank-name assets return-rate account-rate)))
    (define (compute-interest-dishonestly self)
      (let ((old-assets assets))                                        ;***
        (set! assets (+ old-assets (* return-rate old-assets)))         ;***
        (for-each
	 (lambda (account)
	   (let ((interest (* account-rate (ask account 'get-balance))))
	     (let ((rounded-interest (floor interest)))
	       (set! assets (-  assets interest))                       ;***
	       (ask account 'transact rounded-interest 'monthly-interest)
	       (ask *the-stash*
		    'transact
		    (- interest rounded-interest)
		    'anonymous-donor))))
	 (ask self 'get-accounts))
        assets))                                                        ;***
    (define (me message)
      (if (eq? message 'compute-interest)
          compute-interest-dishonestly
          (get-method honest-bank message)))
    me))

In the space below, give a clear, concise explanation of why Louis's
suggestion is unacceptable.  Sketch an example showing how Louis's program
will result in incorrect behavior.  (In this question, you should assume
that the system is running as a simple synchronous system--not the parallel
execution scenario of problem 3.)

Page 10 of 10

PART B. Now that Louis understands why his previous idea doesn't work, he
has another suggestion for changing MAKE-SLEAZY-BANK.  He wants to replace
(ASK SELF 'GET-ASSETS) in the original code by (ASK HONEST-BANK
'GET-ASSETS).  That is, he wants to rewrite the procedure as follows (the
starred lines indicate the changes from the version given in the handout):

(define (make-sleazy-bank bank-name assets return-rate account-rate)
  (let ((honest-bank (make-bank bank-name assets return-rate account-rate)))
    (define (compute-interest-dishonestly self)
      (let ((old-assets (ask honest-bank 'get-assets)))	          ;***
	(ask honest-bank 'set-assets!
	     (+ old-assets (* return-rate old-assets)))	          ;***
	(for-each
	 (lambda (account)
	   (let ((interest (* account-rate (ask account 'get-balance)))
		 (assets (ask honest-bank 'get-assets)))          ;***
	     (let ((rounded-interest (floor interest)))
	       (ask honest-bank 'set-assets! (-	assets interest)) ;***
	       (ask account 'transact rounded-interest 'monthly-interest)
	       (ask *the-stash* 'transact
		    (- interest rounded-interest)
		    'anonymous-donor))))
	 (ask self 'get-accounts))
	(ask honest-bank 'get-assets)))				  ;***
    (define (me message)
      (if (eq? message 'compute-interest)
	  compute-interest-dishonestly
	  (get-method honest-bank message)))
    me))

Check the answer that best describes the effect of Louis's modification:

___ The change will produce an "unbound variable" error when the code is run.

___ The change will change the amount that a sleazy bank puts into *the-stash*.

___ the change has absolutely no effect.  Louis's sleazy bank will
    have the same behavior as the original.

___ Louis's sleazy bank has the same behavior as the original.  But if we
    define a new kind of bank that inherits behavior from a sleazy bank, then
    the new kind of bank could have different behavior when inheriting from
    Louis's sleazy bank than when inheriting from the original sleazy bank.

Give a brief explanation of your answer in the space provided below.


		THIS PAGE WAS INTENTIONALLY LEFT NON BLANK

		  You may write anything you please here