Assignment 12, due Dec 1

Part of the homework for CS:2820, Fall 2017
by Douglas W. Jones
THE UNIVERSITY OF IOWA Department of Computer Science

Assignments are to be turned in on paper. On every assignment, write your name, course and section number at the top. Write your name as it appears in your university records! Use the section number for which you are registered! We will not do detective work to figure out who did what. Work must be legible. Homework is due on paper in discussion section, usually at the start except when the assignment indicates that time to work on the assignment will be provided in class. Exceptions will be made only by advance arrangement with your TA (excepting "acts of God" outside your control). Never push homework under someone's door!

  1. Background: Last week, you worked with this example:
    public class Lazy {
        public static interface Int {
            int eval();
        }
        public static Int add( Int i, Int j ) { return ()->i.eval() + j.eval(); }
        public static Int term( int i ) { return ()->i; }
    
        public static void main(String[] args) {
            Int i = term( 1 );
            Int j = term( 0 );
            for (int x = 0; x < 5; x++) {
                Int k = j;
                j = i;
                i = add( j, k );
                System.out.println( "gets " + k.eval() );
            }
        }
    }
    

    As stated then, this code works, but it is too lazy. Although there are only 5 calls to add, the body of the λ expression inside add is evaluated 7 times, and the number of extra evaluations grows exponentially with each successive iteration of the loop in the main method.

    The problem is that the code given above embodies only one of the two key properties of lazy evaluation. It defers computation until need, but it retains no copy of the values it computes, so if the same lazy Int object is eval'd twice, all the computations are repeated because the object retains no copy of the sum it already computed.

    A problem: Write a new version of add that fixes this and completely matches the full definition of lazyness. (1 point)

    Hint: You can't do it with lambda expressions. You'll have to explicitly return a new object of an appropriate implementation of the Int interface, where that new object has a field it can use to remember its value.

  2. Background: Consider the add method given above.

    A problem: What variables referenced inside this method require some kind of solution to the up-level addressing problem? (0.5 points)

  3. Background: In the notes for Lecture 26 (Nov 28), the Java kluge for uplevel addressing is explained, with an example translated from using an anonymous inner class to an explicitly named outer class with extra parameters to its constructor.

    A problem: Translate the version of add given above to one that uses an explicitly named outer class instead of an inner class. Note, the program is small enough that you can easily test your work. (0.5 points)

  4. Background: The makefile given in Lecture 25 folds the entire problem of compiling the Java code into one make target:
    RoadNetwork.class: classes $(JavaSourceFiles)
    	javac @classes
    

    This misses out on the opportunity to document the inter-file dependencies in our application. In fact, we could have written this:

    mainSupport = ScanSupport.class Errors.class Simulator.class
    RoadNetwork.class: RoadNetwork.java Road.class Intersection.class $(mainSupport)
    	javac RoadNetwork.java
    

    That is, we document all the other classes on which class RoadNetwork depends by referencing their .class files. If we do this throughout, the makefile becomes comprehensive documentation of the relationships between all the classes in the program.

    a) Give an appropriate makefile entry for class ScanSupport. (0.5 points)

    b) Give an appropriate makefile entry for class Road. (0.5 points)