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