Introduction
Featherweight Java (FJ)
Featherweight Generic Java (FGJ)
Translating FGJ into FJ
Java!
Featherweight Java is a `core Java' to look at language features.
FJ = Java - lots of features.
FJ = Non-imperative object calculus + classes + casts
Featherweight Generic Java adds genericity (a.k.a. templates done properly).
FGJ = FJ + F-bounded polymorphism.
Why bother?
Main results:
Subject reduction for FJ and FGJ `Well-typed programs don't get stuck'.
Soundness of a translation from FGJ to FJ.
This validates part of the Generic Java compiler.
Why translate Generic Java to Java? Why not just compile directly?
A sample Featherweight Java program:
class Pair extends Object {
Object fst;
Object snd;
Pair (Object fst, Object snd) {
super (); this.fst = fst; this.snd = snd;
}
Pair setfst (Object newfst) {
return new Pair (newfst, this.snd);
}
}
class A extends Object { A() { super (); } }
class B extends Object { B() { super (); } }
Looks like a Java program!
Some restrictions: no field update, constructors can only initialize fields, ...
What does a linked list class look like?
Featherweight Java has two semantics:
Dynamic semantics e
e'.
Static semantics
e
C
Subject reduction says that these semantics agree.
For example:
new Pair (new A(), new B()).fst
![]()
new A()
and:
new Pair (new A(), new B()).fst
A
What about:
new Cons (new A(), new Cons (new B(), new Nil ())).tail.hd
Gory details in Figure 1 of the full paper (the conference version doesn't include the rule names!).
One technical detail stupid casts:
(T-SCast)
If![]()
![]()
e![]()
D
andC: D
andD: C
and we give a stupid warning
then![]()
![]()
(C)e![]()
C
Why are these needed?
We get subject reduction for FJ...
Theorem (Subject reduction for FJ)
If
e
C
and e
then
e'
e'
C'
for some C' <: C.
We can also show:
Hooray.
A sample Featherweight Generic Java program:
// template class:
class Pair <X extends Object, Y extends Object>
extends Object {
X fst;
Y snd;
Pair (X fst, Y snd) {
super (); this.fst = fst; this.snd = snd;
}
// template method:
<Z extends Object>
Pair<Z,Y> setfst (Z newfst) {
return new Pair<Z,Y> (newfst, this.snd);
}
}
What is the type of:
new Pair <A,B> (new A(), new B()).setfst <C> (new C())
Now what does a linked list class look like?
GJ supports F-bounded polymorphism, for example:
class Ordered <X> {
bool lessThan (X x) { return this.lessThan (x); } // infinite loop!
}
class Integer extends Ordered <Integer> {
int contents;
Integer (int contents) { this.contents = contents; }
bool lessThan (Integer x) { return this.contents < x.contents; }
}
class SortedTree <X extends Ordered <X>> {
... can use x.lessThan (y) if x : X and y : X ...
}
All generic classes are invariant (no variance annotations)!
A gotcha...
We have to be careful about generic casts, for example in Generic Java:
Object foo = new List<A>(); List<B> bar = (List<B>)foo;
this cast is not allowed, but this one is:
List<A> foo = new List<A>(); ConsList<A> bar = (ConsList<A>)foo;
(assuming ConsList<A> extends List<A>).
Why not?
Gory details in Figure 3 of the full paper.
Same results as before...
Theorem (Subject reduction for FGJ)
If
e
T
and e
then
e'
e'
T'
for some T' <: T.
We can compile FGJ to FJ by:
For example, Pair <X,Y> was:
class Pair <X extends Object, Y extends Object>
extends Object {
X fst;
Y snd;
Pair (X fst, Y snd) {
super (); this.fst = fst; this.snd = snd;
}
<Z extends Object>
Pair<Z,Y> setfst (Z newfst) {
return new Pair<Z,Y> (newfst, this.snd);
}
}
to translate this to FJ, we erase all the type parameters
and replace them by Object.
What is the translation of:
new Pair <A,B> (
new A(),
new B()
).fst
What about:
new Pair <A,B> (
new A(),
new Pair <B,C> (
new B(),
new C()
).fst
).snd
We'd like:
Ife![]()
e'in FGJ
then|e|*
|e'|
(where |e| is the translation of FGJ into FJ).
Unfortunately it's not true due to casts!
new Pair <A,B> (
new A(),
new Pair <B,C> (
new B(),
new C()
).fst
).snd
(do the snd before the fst and oh dear...)
Write e if we can get from
e'e
to e' by changing synthetic casts.
The result is:
Ife![]()
e'in FGJ
then|e|*
d|e'| in FJ
which proves that a fragment of the GJ compiler is correct!
Last formal lecture: A Concurrent Object Calculus by Gordon and Hankin.