CSE 505 - Autumn 1993 - Midterm Sample Solution 1a. in procedure oak 10 in main program 10 1b. in procedure oak 1 in main program 10 2a. 2 3 11 11 2b. 2 3 11 3 There is a potential ambiguity here, depending on which order j and k are copied back to the actual parameter. Here, I assume first j is copied, then k. 2c. 14 14 14 14 3a. [num]->[num] 3b. (*->**)->(***->*)->***->** 3c. (*->num)->*->num 3d. (*->*->*)->*->tree *->* 3e. num 3f. num 3g. Node 10 (Node 11 (Node 12 (Node 13 (Node 14 (Node 15 (Node 16 ... 3h. Node False (Node True (Node False (Node False (Node False ... 3i. True 3j. doesn't terminate <> 4. If p just sent the message to point without using delegation, when the move method in point asked the object for its current x and y values, these message would go to the prototype point, rather than back to p. If we use delegation, since p is delgating move to point, when it sends a message such as "self x", "self" refers back to p. 5a. In Extended Smalltalk, sending the message clam to an instance of D would execute the clam method in A. Even though clam is inherited via two paths, since it is the same method in each case, Extended Smalltalk regards the situation as unambiguous. Sending the message squid gives an ambiguity, since squid is defined in both B and C, and so D inherits two different squid methods. 5b. CLOS forms a linear ordering of D and its superclasses, namely D B C A. When the message clam is sent, it searches this linearized order, finds the method in A, and executes it. When the message squid is sent, it searches this linearized order, finds the method in B, and executes it; there is no ambiguity. 5c. In Snyder's system, sending the message clam to an instance of D would yield an error. Even though it is defined only in A, Snyder takes a tree-structured view, in which A as inherited by B is separate from the A that is inherited by C; so that in this case there is an ambiguity error. Sending the message squid finds the version in both B and C, and so is an error as well. 6a. nextPutAll(a : array[T]) 6b. WriteStream[Object] is a subtype of WriteStream[Character]. (Actually, if the array passed to nextPutAll is writeable as well as readable, then there is no subtype relation between Array[Object] and Array[Character], and hence there is no subtype relation between WriteStream[Object] and WriteStream[Character]! However, I accepted either answer.) 6c. ReadStream[Character] is a subtype of ReadStream[Object] 6c. ReadWriteStream[Character] is a subtype of both ReadStream[Character] and WriteStream[Character]. ReadStream[Character] and WriteStream[Character] are not related. 7. For multiple abstract subtyping, no additional issues arise over single subtyping. A type S is a subtype of T1 and T2 if it is a subtype of T1 and is also a subtype of T2. (See 6c for example.) There are no questions of conflicting inherited types and the like -- to be a subtype of T1 and T2, S must conform to both. For multiple implemenation inheritance, the problems that arise are what to do about conflicting inherited methods, what about duplicate instance variables, and whether a graph-oriented or tree-oriented approach is used. Some approaches to these questions are exhibited by Extended Smalltalk (which treats conflicts as an error, and uses a graph approach), CLOS (which linearizes the superclasses, so that conflicts are always resolved, and which again uses a graph-oriented approach), and Snyder's system (which again treats conflicts as an error, and uses a tree approach). 8. In single dispatching, only the first argument is significant in deciding which method to use for a given message. In multiple dispatching, potentially all of the arguments are significant. Single dispatching is simpler, and arguably more object-oriented (since the method is clearly associated with the receiving object only). It is also more natural for distributed object-oriented systems. Multiple dispatching is more powerful, and more natural for binary operations such as +, as well as other kinds of operations for which several arguments are significant, e.g. display(object,device). Multiple dispatching is more complex, and some have argued that it is less object-oriented, since the method doesn't reside just in the receiver (or the receiver's class). (Cecil attempts to deal with the latter problem by regarding the method as being a part of each argument that has a concrete type annotation.) 9a. false 9b. true 9c. true 9d. true 9e. true (I didn't actually grade this question, though)