Typed Lambda Calculus

advertisement
Featherweight Java
Chapter 19
Benjamin Pierce
Types and Programming Languages
Eiffel, 1989
Cook, W.R. (1989) - A Proposal for Making Eiffel Type-Safe, in
Proceedings of ECOOP'89. S. Cook (ed.), pp. 57-70. Cambridge University
Press.
Betrand Meyer, on unsoundness of Eiffel:
“Eiffel users universally report that they almost never
run into such problems in real software development.”
Ten years later: Java
Interesting Aspects of Java
• Object Oriented
– (Almost) everything is an object
– Single inheritance
• Adding fields
• Method override
• Open recursion
– Interfaces
– Encapsulation
•
•
•
•
Reflection
Concurrency
Libraries
Type safety
– Well typed programs have no undefined semantics
Featherweight Java
• (Minimal) Purely functional object oriented strict subset of Java
• Supports
– Everything is an object
– Single inheritance
• Adding fields
• Method override
• Open recursion
• Simple
– Operational Semantics
– Type Checking
– Proof of safety
• Extensions
– Interface
– Inner classes
– Polymorphism
Featherweight Java
CL ::=
class declarations
class c extends C { C f ; K M }
K ::=
constructor declarations
C (C f) { super(f) ; this.f=f ;}
M ::=
method declarations
C m(C x) { return t;}
t ::=
terms
x
variable
t.f
field access
t.m(t) method invocation
new C(t) object creation
(C) t
cast
v::=
values
new C(v)
A Simple Example
class Bicycle extends object {
class MountainBike extends Bicycle {
int currentSpeed ; // field
int LowerGear;
int currentGear ; // field
MountainBike(int s, int g, int l) {
Biycle(int s, int g) { // constructor
super(s, g) ;
super() ;
this.LowerGear= l ; }
this.currentSpeed= s ;
Bicycle UpShift ()
this.currentGear= g ;
}
Bicycle UpShift ()
{ …}
}
{
class Main extends object {
return new Bicycle(this.currentSpeed, Bicycle b;
this.currentGeer+1) ; }
Main() {
super() ; this.b = new MountainBike(3, 3, 5); }
}
Bicycle UpShift() {
return this.b.UpShift() ; }
}
Running example
class A extends Object { A() { supper(); } }
class B extends Object { B() { supper(); } }
class Pair extends Object {
Object first;
Object second;
Pair(Object fst, Object snd) {
supper();
this first=fst;
this second = snd;
}
Pair SetFst(Object newfst) {
return new Pair(newfst, this.snd);
}
}
Nominal vs. Structural Type Systems
• When are two types equal:
• Structural equivalence
– Two isomorphic types are identical
– NatPair = {fst: Nat, snd: Nat}
• Nominal (name equivalence) type systems
– Compound types have name
– The name caries significant information
– Type name must match
Nominal vs. Structural Type Systems
Nominal
• Type name is useful at
runtime
– “Generic” programming
– Efficient runtime checks
• Naturally supports recursive
types
• Efficient subtyping checks
• Prevent “spurious”
subsumption
Structural
• Type expressions are closed
entities
• Supports type abstractions
–
–
–
–
Parametric polymorphism
Abstract data types
User defined type operators
…
The Class Table
• Maps class names to their class definitions
(excluding objects)
Running example
class A extends Object { A() { supper(); } } A
class A extends Object {…}
class B extends Object { B() { supper(); } } B
class B extends Object {…}
class Pair extends Object {
Pair
Object first;
Object second;
Pair(Object fst, Object snd) {
supper();
this first=fst;
this second = snd;
}
Pair SetFst(Object newfst) {
return new Pair(newfst, this.snd);
}
}
class Pair extends Object {…}
Featherweight Java with subtyping
CL ::=
class declarations Subtyping
class c extends C { C f ; K M }
K ::=
constructor declarations
C (C f) { super(f) ; this.f=f ;}
M ::=
method declarations
C m(C x) { return t;}
t ::=
v::=
terms
x
variable
t.f
field access
t.m(t) method invocation
new C(t) object creation
(C) t
cast
values
new C(v)
C <: D
C <: C
C <: D
D <:E
C <: E
CT(C) = class C extends D {… }
C <: D
The Class Table
• Maps class names to their class definitions (excluding
objects)
• A program is a class table and a term
• Consistency requirements
–
–
–
–
<: is acyclic (<: is a partial order)
CT(C)= class C … for every C in dom(CT)
Object  dom(CT)
For every class C appearing in CT except Object, c 
dom(CT)
• fields(C) = C f are the fields declared in C
• mbody(m, C) = (x, t) where x are the formal arguments
and t is m’s body
Plan
•
•
•
•
A small step operational semantics
Potential runtime errors
Basic type system
Corrections
New Evaluation
ti t’i
new C(v, ti, t) new C(v, t’i, t)
(E-New-Arg)
Field Projection
fields(C) = C f
(E-ProjNew)
new C(v).fi  vi
new Pair(new A(), new Pair(new A(), new B())).snd  new Pair (new A(), new B())
t0 t’0
(E-Field)
t0.f  t’0.f
new Pair(new A(), new Pair(new A(), new B())).snd.fst  new A()
Method Invocation
• Use the (actual) class to determine the exact
method
• Bind actual parameters to formals
• Benefit from absence of side effects
Method Invocation
mbody(m, C) =(x, t0)
new C(v).m(u) [x
(E-InvNew)
u, this
new C(v)] t0
new Pair(new A(), new B()).setfst(new B())
[newfst
new B(), this
new Pair(new A(), new B())] new Pair(newfst, this.snd)
=new Pair(new B(), new Pair (new A(), new B()).snd) 
new Pair(new B(), new B())
(E-ProjNew)
Method Invocation
mbody(m, C) =(x, t0)
new C(v).m(u) [x
(E-InvNew)
u, this
t0  t’0
new C(v)] t0
(E-InvkRecv)
t0. m(t) t’0.m(t)
ti  t’i
v0. m(v, ti, t) v0.m(v, t’i, t)
(E-InvArg)
Cast Invocation
• Assure that the casting is valid
• Convert the type
Cast Invocation
C <: D
(E-CastNew)
(D) (new C(v)) new C(v)
t0  t’0
(E-Cast)
(C) t0 (C) t’0
((Pair) new Pair(new Pair (new A(), new B()), new A()).fst).snd 
(E-ProjNew)
((Pair) new Pair(new A(), new B())).snd 
(E-CastNew)
new Pair(new A(), new B()).snd 
new B()
(E-ProjNew)
FJ Semantics Summary
fields(C) = C f
t0 t’0
(E-ProjNew)
new C(v).fi  vi
t0.f  t’0.f
mbody(m, C) =(x, t0)
new C(v).m(u) [x
(E-Field)
(E-InvNew)
u, this
new C(v)] t0
t0  t’0
(E-InvkRecv)
t0. m(t) t’0.m(t)
ti t’i
(E-InvArg)
v0. m(v, ti, t) v0.m(v, t’i, t)
C <: D
(D) (new C(v)) new C(v)
(E-CastNew)
ti  t’i
(E-New-Arg)
new C(v, ti, t) new C(v, t’i, t)
t0  t’0
(C) t0 (C) t’0
(E-Cast)
Potential Runtime Errors
• Incompatible constructor invocation
– new Pair(new A())
• Incompatible field selection
– new Pair(new A(), new B()).thrd
• Incompatible method invocation “message not
understood”
– new A().setfst(new B())
• Incompatible arguments of methods
• Incompatible return value of methods
• Incompatible downcasts
The Class Table
• Maps class names to their class definitions
(excluding objects)
• A program is a class table and a term
• fields(C) = C f are the fields declared in C
• mbody(m, C) = (x, t) where x are the formal
arguments and t is the method body
• mtype(m, C) = B  B where B is the type of
arguments and B is the type of the results
• override(m, D, C  C0) holds if the method m
with arguments C is redefined in a subclass of D
Featherweight Java Type Rules
 t : C
x : C 
 x : C
(T-VAR)
  t0 : C0 fields(C0)=C f
 t0 .fi : Ci
C <: D C != D
  t0: D
(T-DCAST)
 (C) t0: C
(T-FIELD)
Method Typing
M OK in C
x: C, this: C  t0 : E0 <: C0
E0
CT(C)=class
C extends D {…}
  t0 : C0 mtype(m, C0)= D  C
t:C
C <: D
(T-INVK) override(m, D, C  C0)
 t0 .m(t): C
C0 m(C x) { return t0 ; } OK in C
fields(C)= D f
Class Typing
C OK
C <: D
t:C
(T-NEW)
 new C (t): C
K= C(D g, C f) {super(g); this.f = f;}
fields(D)=D g
M ok in C
D <: C
  t0: D
(T-UCAST)
 (C) t0: C
class C extends D { C f K M } OK
Type Safety(19.5)
• Well typed programs cannot go wrong
– No undefined semantics
– No runtime checks
• If t is well typed then either t is a value or there
exists an evaluation step t  t’ [Progress]
• If t is well typed and there exists an evaluation
step t  t’ then t’ is also well typed
[Preservation]
Type Preservation: Take 1
• If  t : C and t  t’ then  t’ : C
• Counterexample
(Object) new B()  new B() (E-CastNew)
Type Preservation: Take 2
• If  t : C and t  t’ then there exists C’ such
that C’ <: C and  t’ : C’
• Counterexample
– (Object) new B()  new B() (E-CastNew)
– (A) (Object) new B()  (A) new B() (E-Cast)
 t : C
x : C 
 x : C
Featherweight Java Type Rules
  t0: D C : D
stupid warning
(T-VAR)
  t0 : C0 fields(C0)=C f
 t0 .fi : Ci
D :C
 (C) t0: C
(T-SCAST)
(T-FIELD)
Method Typing
M OK in C
  t0 : C0 mtype(m, C0)= D C
x: C, this: C  t0 : E0 <: C0
t:C
C <: D
(T-INVK) CT(C)=class
E0
C extends D {…}
 t0 .m(t) : C
override(m, D, C  C0)
fields(C)= D f
C0 m(C x) { return t0 ; } OK in C
C <: D
t:C
(T-NEW)
Class Typing
 new C (t): C
C OK
D <: C
  t0: D
 (C) t0: C
(T-UCAST)
C <: D C != D
  t0: D
(T-DCAST)
 (C) t0: C
K= C(D g, C f) {super(g); this.f = f;}
fields(D)=D g
M ok in C
class C extends D { C f K M } OK
Progress Theorem
• If a program is well typed then the only way to
get stuck is if it reaches a point in which it
cannot perform a downcast
• If t is a well typed term
– If t = new C0(t).f then fields(C0) = C f and f  f
– If t = new C0(t).m(s) then mbody(m, C0) = (x, t0)
and |x| = |s|
• if t is a closed well typed in a normal form
then either t is a value or “t is a cast”
Evaluation Contexts
• Terms with a hole
E ::=
evaluation contexts
[]
hole
E.f
field access
E.m(t)
method invocation (receiver)
v.m(v, E, t) method invocation (arg)
new C(v, E, t) object creation(arg)
(C) E
cast
• E[t] denotes the term obtained by replacing the hole with t
• If t  t’ then t= E(r) and t’= E(r’) where E, r, and r’ are unique and r  r’ is
one of the rules E-ProjNew, E-InvNew and E-CastNew
• If t is closed well defined normalized term then either t is a value or for
some context E we can express t as t = E[(C)(new D(v)] where D
:C
(Progress theorem)
Encoding vs. Primitive Objects
• Two approaches for semantics and typing OO
programs
– Typed lambda calculus with records, references
and subtypes (Chapter 18)
– Object and classes are primitive mechanisms
Summary
• Establishing type safety of real programming
language can be useful
• Mechanized proof systems (Isabele, Coq) can
help
– Especially useful in the design phase
• But indentifying a core subset is also useful
Quotes
• “Inside every large language there is a small
language struggling to come out”
– Igarashi, Pierce, and Wadler (1999)
• “Inside every large program there is a small
program struggling to come out”
– Sir Tony Hoare, Efficient Production of large
programs (1970)
• “I’m fat but I’m thin inside”
– George Orwell, Coming Up from Air (1939)
Download