Homework # 9
due November 8
Please read Chapter 18-19 in the textbook.
Extend the counter class with a new ``class'' of variable counter
class, with a new method setinc that sets the step size which
is used by a new definition for inc that increments by the
current step size. The code should use ascription so that the
record types are given useful names.
Use the fullref to check your code.
Here is a simple test case:
vc1 = newVarCounter(2);
vc2 = newVarCounter(3);
inc3 vc1;
inc3 vc2;
vc1.get unit;
vc2.get unit;
vc1.setinc(1);
inc3 vc1;
inc3 vc2;
vc1.get unit;
vc2.get unit;
Leave your code (including the definitions of Counter,
CounterRep and related functions) in a file varinc.f
in your homework9 directory.
Note that open recursion is not needed for this program.
Please do the following problems
- Exercise 19.4.1
- Exercise 19.4.5
- Even in the absence of interfaces and conditional expressions,
Java has problems with subsumption (T-SUB) because of static
overloading
resolution. Give a simple Java program that would type-check (and
run) if subsumption were permitted for any expression, but that does
not type-check in standard Java unless upcasts are added (in the place
where T-SUB is used). Note that upcasts never fail.
Hint: Your example will need to use overloaded functions where the
options have different result types.
This model of objects uses a ``protected'' record of fields and a
``public'' record of functions.
- Show how we could (cleanly) model:
- private mutable fields
- public mutable fields
- multiple constructors (but same fields)
For each thing, make sure you can still handle subclassing.
- What sort of space usage does it have?
Suppose we wish to model a C++ class with one private mutable data
member and 25 member functions. How much space would 1000 objects
take up ?
Compare with how C++, Java or Cool
is implemented. (If you haven't taken CS 654, you should consult a
compiler textbook, such as Michael Scott's Programming
Language Pragmatics, on how dynamic dispatch is implemented.)
- C++, Java and Cool can be more efficient, because the ``self''
object is passed as a parameter to the method rather than being
available in the environment. Then calling (say) the set
method of counter c, one would write:
(c.inc) c
assuming we have a counter such as:
c = { get = lambda self . !(r.x) ,
set = lambda self . lambda i . r.x := i,
inc = lambda self . (self.set) self (succ ((self.get) self)) };
Redo the open recursion through ``self'' examples from Chapter 18
using this approach. Use fulluntyped to test your
implementation. Put your result in object.f in your
homework9 directory.
- What goes wrong if you try to get this code to work with types?
About this document
John Tang Boyland
2005-11-03