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: Thu Nov 13 13:15:21 Eastern Standard Time 2014