Com S 342 --- Principles of Programming Languages HOMEWORK 7: PARAMETER PASSING (File $Date: 1997/12/04 04:32:12 $) Due: problems 1,3,4,6 December 5. As an explicit exception to the course policies, we will accept late homework for the regular problems of this homework on December 8 with a 10% penalty. However, no late homework will be accepted after December 8. No other late homework will be accepted after December 5. No extra credit work at all will be accepted after December 5. (Consider the extra credit problems to be suggested practice after that.) In this homework, you will learn about the semantics of objects and inheritance as found in singly-dispatched object-oriented (OO) languages such as C++, Java, Smalltalk, etc. This will help you use the languages you know better, and to learn new languages faster. For code hand in *both* your printout of the Scheme code and a transcript of testing. See the directory $PUB/data/hw6/hw7.tst for test data for each coding problem. The section headings below give the readings related to the problems. Please read them in chapter 7 of the textbook. (There are more suggestions at the end of this homework.) ESSENTIALS OF PROGRAMMING LANGUAGES: Section 7.1 1. (15 points) [understanding how to simulate objects with closures] Consider figure 7.1.1 in the text and the transcript on pages 215-216. This code is in $PUB/eopl/sources.ss if you want to test it out. (a) Draw a picture like those we have been drawing in class for the state at the end of the transcript. Be sure to include the closures and the environments for each let. (b) Why are there two let expressions in Figure 7.1.1? (c) Why would the code for Figure 7.1.1 not work as desired if the let expressions were moved inside the lambda expressions? 2. (suggested practice) [multiple implementations coexisting] Do exercise 7.1.1 in the text. 3. (30 points) [method-application] Do exercise 7.1.2 in the text. Your code should be a modification of $PUB/lib/ch7-1.scm; one way to do this is to start your solution with (load-from-lib "ch7-1.scm") and then copy into your solution that the code from eval-exp in the file $PUB/lib/ch7-1.scm. Test your code using (test-hw7 "method-application") Please highlight the changed cases in your code so we can find them easily. Hint: Think about the types in the code you write! As in chapter 6, in this chapter eval-rand returns a denoted value, however meth-call, for example, takes a list of expressed values. Also, you may need to use the function defined-in-env?, which is part of the environment ADT, but not documented in the book. See the file $PUB/lib/environments.scm. 4. (15 points) [use self in Scheme objects] (a) Do exercise 7.1.6 in the text. (You can find the code for figure 7.1.1 in the file $PUB/eopl/sources.ss. Also the words "class operations" in the wording of the problem should be "class's operations"; because these are really instance operations in the standard OO terminology.) (b) Which occurrences of the expression (null? stk) your version of Figure 7.1.1 can be changed to (self 'empty?) without creating an infinite loop when your version of the figure is used? (c) Make the changes you described in part (b), and test your code to make sure that the changes you made work and do not cause infinite loops. 5. (20 points extra credit) [make self an instance variable] Do exercise 7.1.7. 6. (30 points) [instance-vars-shadow] Do exercise 7.1.9 in the text. For example, consider the following definitions. define x = 13; define z = 5; define testclass = simpleclass () (x, y) (initialize = method () begin x := 0; y := 3 end; getx = method() x; gety = method() y; getz = method() z; addx = method (z) begin x := +(z,x); x end; addy = method (x) begin y := +(x,y); y end; combine = method () let y = +(x,3) in begin x := *(x,y); x end ) 0; define tester1 = simpleinstance testclass Then, for example, the global x has a hole in its scope within the class. However, the instance variable x has a hole in its scope in the method addy, since the formal parameter named x in that method is not free. Similary, the body of the let in the combine method is a hole in the scope of the instance variable y. So, after executing the above definitions, we would have the following sequence of test results (the later ones are considered to execute in the state modified by the earlier ones. $getx(tester1) ==> 0 $gety(tester1) ==> 3 $getz(tester1) ==> 5 $addx(tester1, 7) ==> 7 $getx(tester1) ==> 7 $addy(tester1, 100) ==> 103 $getx(tester1) ==> 7 $gety(tester1) ==> 103 $combine(tester1) ==> 70 $getx(tester1) ==> 70 $gety(tester1) ==> 103 It's easy to think that what needs to be done is to first test a varref to see if it's an instance variable, however, this would not handle the holes that may appear in the scopes of instance variables because of local declarations within methods. Hence, what you need to do is (a) delete the i-varref and i-varassign cases from eval-exp, and (b) change the method case so that the environment used to evaluate the body of a method has the right scope. Note that you are not making any change for class variables in this problem. Your code should be a modification of $PUB/lib/ch7-1.scm (not a previous exercise). That is, in your solution, first use (load-from-lib "ch7-1.scm") and then follow this with the procedure definitions you need to change or add. Test your code using (test-hw7 "instance-vars-shadow") Please highlight the changed cases in your code so we can find them easily. ESSENTIALS OF PROGRAMMING LANGUAGES: Sections 7.2 7. (15 points extra credit) [counting instances in the defined OO language] Do exercise 7.2.1 in the text. You will have to test this yourself. 8. (suggested practice) [Making super a pseudo-variable] Do exercise 7.2.2 in the text. 9. (40 points extra credit) [Another representation for method environments] Do exercise 7.2.3 in the text. 10. (30 points extra credit) [dynamic-inheritance for class and instance variables] Do exercise 7.2.4 in the text. In your solution, first use (load-from-lib "ch7-2.scm") and then follow this with the procedure definitions you need to change or add. You will need to copy the code for eval-exp into your file from $PUB/lib/ch7-2.scm and change the i-varref, c-varref, i-varassign, and c-varassign cases. Note that class variables will be referenced and assigned in the initial expression for a class, and at that time the inst argument to eval-exp is not an instance record; so you may want to use code like the following to compute the dynamic class in the c-varref and c-varassign cases: (if (not (instance? inst)) class (instance->class inst)) Test your code using (test-hw7 "dynamic-inheritance") Please highlight the changed cases in your code so we can find them easily. ESSENTIALS OF PROGRAMMING LANGUAGES: Sections 7.3 11. (10 points extra credit) [drawing a diagram for meta-classes] Do exercise 7.3.1 in the text. 12. (suggested practice) [modification in the defined language] Do exercise 7.3.2 in the text. WHERE TO GO FROM HERE Well, this is where the homework stops, but the book, and this topic keep on going. It's definitely worth reading the last part of chapter 7 in the book, section 7.3, to find out about abstraction at the class level. (This is a feature that is in Smalltalk, but isn't supported well in C++, and is marginal in Java; however it will show up again in future languages.) If you are interested in more about OO programming techniques, For a basic introduction to the terminology and goals of OO programming, see Brad Cox, ``Object Oriented Programming: an Evolutionary Approach'' (Addison-Wesley, 1996). Slightly more advanced, but highly recommended is Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides's ``Design Patterns'' (Addison-Wesley, 1995). Another book that I like is Arthur Riel's ``Object-Oriented Design Heuristics'' (Addison-Wesley, 1996). There are many others about specific languages, such as C++. The rest of our textbook goes in a different direction, and studies control, with the aim of transforming interpreters into compilers! If you are interested, read chapter 4, sections 4.1-4.3 first, and then you should know enough to do this on your own. We can also recommend other books on programming languages if you would like to study the topic further.