Guided Practice 10.1 - Solution

The question was:

Imagine we are working in a class called Class1%, with init-fields x, y, and z (all containing integers).

Consider the following method definition:

;; Number -> Class1%
;; GIVEN: a number u
;; RETURNS: an object just like this one, except that the new x field contains
;; x+y, and the new y field contains z+u.
(define/public (method1 u)
  (new Class1%
    [x (+ x y)]
    [y (+ z u)]
    [z z]))

Your task is to transform this into an imperative method using the Void transform. The new contract and purpose statement are:

;; Number -> Void
;; GIVEN: a number u
;; EFFECT: alters the fields of this object so that  the new x field
;; contains the value of x+y, and the new y field contains the value
;; of z+u.

;; EXAMPLE: if obj1 has fields x=10, y=20, and z=100, then calling
;; (send obj1 method1 5)
;; should leave obj1 with fields x=30, y=105, z=100.

Which of the following are correct versions of the new method?

Answer:

Versions 2, 3, and 4 are correct. Versions 1 and 5 are incorrect. Let's look at each one in more detail.

;;; Version 1:

(define/public (method1 u)
  (new Class1%
    [x (+ x y)]
    [y (+ z u)]))

;; Ans: incorrect.  This returns a new object instead of altering the
;; current one.  Also, this initialization will fail because it does
;; not give a value for z.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Version 2:

(define/public (method1 u)
  (set! x (+ x y))
  (set! y (+ z u)))

;; Ans: correct.  The value of z is unchanged, so there is no need to
;; set! it.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Version 3:

(define/public (method1 u)
  (set! x (+ x y))
  (set! y (+ z u))
  (set! z z))

;; Ans: correct.  The value of z is unchanged, so this set! does the
;; right thing.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Version 4:

(define/public (method1 u)
  (set! x (+ x y))
  (set! z z)
  (set! y (+ z u)))

;; Ans: correct.  The assignments do not have to be in the same order, so
;; long as the fields get the correct values.

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;

;;; Version 5:

(define/public (method1 u)
  (set! y (+ z u))
  (set! x (+ x y)))

;; Ans: incorrect.  The set! to x will see the new value of y, not the old
;; one.  When writing imperative code you must be careful about the
;; order of assignments.

Last modified: Tue Nov 10 22:32:54 Eastern Standard Time 2015