type inference in java 8 - ba-horb.depl/talks/oberseminar_ti_java8.pdf · martin pluemicke's...
TRANSCRIPT
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Type inference in Java 8
Martin Plumicke
Baden-Wuerttemberg Cooperative State UniversityStuttgart/Horb
10. Januar 2013
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Overview
IntroductionResearch overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Type inference algorithm TIThe function TYPE
The sub-function TYPEExprThe sub-function TYPEStmt
The function SOLVEThe whole algorithm TI
Implementation
Summary and Outlook
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
− Additional functional interfaces as target types of lambda
UNIF’04:
Type unification in Generic−Java
− Type unification for generic java types without wildcards
WLP2007/INAP2007:
Java type unification with wildcards
− Type unification for generic java types with wildcards
− λ −expressions, but no methodsλ
PPPJ 2011:
Well−typings for Java
− Function−types as types of PPPJ 2008:
Imtersection types in java
− Resolving the intersection types for code generation
Implementierung eines Typinferenzalgorithmus für Java 8
PPPJ 2006:
Typeless programming in Java 5.0
− Type inference for generic java types without wildcards
PPPJ 2007:
Typeless programming in Java 5.0 with wildcards
− Type inference for generic java types with wildcards
− Adaption of the type inference algorithm of Fuh and Mishra ’88
results: well−typings (condtional types)
− Functional interfaces as types of λ −expressions
result: set of type results with some constraints
λ−expressions
2014 (to publish):
More type−inference in java 8
− Type inference for λ −expressions
KPS 2013:
Work in progress/TO DO:
− Eclipse PlugIn
− Resolving the intersection types for code generation
− Resolving the intersection types for code generation
2014 (to publish):
Functional interfaces vs. function types in Java with lambdas
− function−types as types of λ −expressions
expressions
Martin Pluemicke’s research on type inference for Java with generics and lambda expressions (version 5 − 8)
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
History of Java type system
Version 1:
I Subtyping on classes (without parameters)Ex.: Integer≤∗ Object
Version 5:
I Parametrized classes (type constructors)Ex.: Vector<X>
I Subtyping extensionEx.: Matrix≤∗ Vector<Vector<Integer>>
I Wildcards (with lower and upper bounds)Ex.: Vector<? extends Integer>
Version 8: I Lambda–expressionsI Functional interfaces, but no function types
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
History of Java type system
Version 1:
I Subtyping on classes (without parameters)Ex.: Integer≤∗ Object
Version 5:
I Parametrized classes (type constructors)Ex.: Vector<X>
I Subtyping extensionEx.: Matrix≤∗ Vector<Vector<Integer>>
I Wildcards (with lower and upper bounds)Ex.: Vector<? extends Integer>
Version 8: I Lambda–expressionsI Functional interfaces, but no function types
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
History of Java type system
Version 1:
I Subtyping on classes (without parameters)Ex.: Integer≤∗ Object
Version 5:
I Parametrized classes (type constructors)Ex.: Vector<X>
I Subtyping extensionEx.: Matrix≤∗ Vector<Vector<Integer>>
I Wildcards (with lower and upper bounds)Ex.: Vector<? extends Integer>
Version 8: I Lambda–expressionsI Functional interfaces, but no function types
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Motivating Example: External Iteration
public class Student {String name;
int graduationYear;
double score; }
List<Student> students = ...
double highestScore = 0.0;
for (Student s : students) {if (s.gradYear == 2013) {if (s.score > highestScore) {highestScore = s.score;
}}
}
I external iteration
I serial iteration
I not thread-safe
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Motivating Example: External Iteration
public class Student {String name;
int graduationYear;
double score; }
List<Student> students = ...
double highestScore = 0.0;
for (Student s : students) {if (s.gradYear == 2013) {if (s.score > highestScore) {highestScore = s.score;
}}
}
I external iteration
I serial iteration
I not thread-safe
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Motivating Example: External Iteration
public class Student {String name;
int graduationYear;
double score; }
List<Student> students = ...
double highestScore = 0.0;
for (Student s : students) {if (s.gradYear == 2013) {if (s.score > highestScore) {highestScore = s.score;
}}
}
I external iteration
I serial iteration
I not thread-safe
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Motivating Example: Inner classes
public class Student {String name;
int graduationYear;
double score; }
SomeCoolList<Student> students = ...
double highestScore =
students.filter(new Predicate<Student>() {public boolean op(Student s) {return s.getGradYear() == 2013; }
})
.map(new Mapper<Student,Double>() {public Double extract(Student s) {return s.getScore(); }
}).max();
I internal iterationby inner classes
I traversal may bedone in parallel
I but ugly syntax
Idea: Lambda–expressions
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Motivating Example: Inner classes
public class Student {String name;
int graduationYear;
double score; }
SomeCoolList<Student> students = ...
double highestScore =
students.filter(new Predicate<Student>() {public boolean op(Student s) {return s.getGradYear() == 2013; }
}).map(new Mapper<Student,Double>() {public Double extract(Student s) {return s.getScore(); }
})
.max();
I internal iterationby inner classes
I traversal may bedone in parallel
I but ugly syntax
Idea: Lambda–expressions
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Motivating Example: Inner classes
public class Student {String name;
int graduationYear;
double score; }
SomeCoolList<Student> students = ...
double highestScore =
students.filter(new Predicate<Student>() {public boolean op(Student s) {return s.getGradYear() == 2013; }
}).map(new Mapper<Student,Double>() {public Double extract(Student s) {return s.getScore(); }
}).max();
I internal iterationby inner classes
I traversal may bedone in parallel
I but ugly syntax
Idea: Lambda–expressions
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Motivating Example: Inner classes
public class Student {String name;
int graduationYear;
double score; }
SomeCoolList<Student> students = ...
double highestScore =
students.filter(new Predicate<Student>() {public boolean op(Student s) {return s.getGradYear() == 2013; }
}).map(new Mapper<Student,Double>() {public Double extract(Student s) {return s.getScore(); }
}).max();
I internal iterationby inner classes
I traversal may bedone in parallel
I but ugly syntax
Idea: Lambda–expressions
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Motivating Example: Inner classes
public class Student {String name;
int graduationYear;
double score; }
SomeCoolList<Student> students = ...
double highestScore =
students.filter(new Predicate<Student>() {public boolean op(Student s) {return s.getGradYear() == 2013; }
}).map(new Mapper<Student,Double>() {public Double extract(Student s) {return s.getScore(); }
}).max();
I internal iterationby inner classes
I traversal may bedone in parallel
I but ugly syntax
Idea: Lambda–expressions
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Lambda–expression
Well-known from functional programming languages.
Example: Identity–function
\x -> x -- HASKELL
fn x => x -- SML
(lambda (x) x) -- SCHEME
Application: (\x -> x) 1 = 1
Function-types: (\x -> x) :: a -> a
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Lambda–expression
Well-known from functional programming languages.
Example: Identity–function
\x -> x -- HASKELL
fn x => x -- SML
(lambda (x) x) -- SCHEME
Application: (\x -> x) 1 = 1
Function-types: (\x -> x) :: a -> a
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Lambda–expression
Well-known from functional programming languages.
Example: Identity–function
\x -> x -- HASKELL
fn x => x -- SML
(lambda (x) x) -- SCHEME
Application: (\x -> x) 1 = 1
Function-types: (\x -> x) :: a -> a
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Motivating Example: Lambda–expressions
public class Student {String name;
int graduationYear;
double score; }
SomeCoolList<Student> students = ...
double highestScore =
students.filter(Student s -> s.getGradYear() == 2013)
.map(Student s -> s.getScore())
.max();
I Lambda–expressions
I more readable
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Motivating Example: Lambda–expressions
public class Student {String name;
int graduationYear;
double score; }
SomeCoolList<Student> students = ...
double highestScore =
students.filter(Student s -> s.getGradYear() == 2013)
.map(Student s -> s.getScore())
.max();I Lambda–
expressions
I more readable
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Java 8 features
I Lambda–expressions
I functional interfaces
I restricted type inference
I method references
I default methods
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Functional interfaces (SAM–Types)
An interface with one method
Example:
interface Operation {public int op (int x, int y);
}
int doOp(Operation o, int a, int b)
{return o.op(a, b);
}...
doOp((int x, int y) -> x + y, 5, 7);
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Functional interfaces (SAM–Types)
An interface with one method
Example:
interface Operation {public int op (int x, int y);
}
int doOp(Operation o, int a, int b)
{return o.op(a, b);
}...
doOp((int x, int y) -> x + y, 5, 7);
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Functional interfaces in the Java library
interface Comparator<T> { int compare(T x, T y); }interface FileFilter { boolean accept(File x); }interface DirectoryStream.Filter<T> { boolean accept(T x); }interface Runnable { void run(); }interface ActionListener { void actionPerformed(...); }interface Callable<T> { T call(); }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Target types
I lambda expressions have no explicit type
I a target type is deduced from the context
Example:
Operation op = (int x, int y) -> x + y
⇒ Target type: Operation
Runnable op = (int x, int y) -> x + y
⇒ Target type: Runnable
Which is a correct target type?
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Target types
I lambda expressions have no explicit type
I a target type is deduced from the context
Example:
Operation op = (int x, int y) -> x + y
⇒ Target type: Operation
Runnable op = (int x, int y) -> x + y
⇒ Target type: Runnable
Which is a correct target type?
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Target types
I lambda expressions have no explicit type
I a target type is deduced from the context
Example:
Operation op = (int x, int y) -> x + y
⇒ Target type: Operation
Runnable op = (int x, int y) -> x + y
⇒ Target type: Runnable
Which is a correct target type?
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Functional interfaces as compatible target types
A lambda expression is compatible with a type T , if
I T is a functional interface type
I The lambda expression has the same number of parameters as T ’smethod, and those parameters’ types are the same
I Each expression returned by the lambda body is compatible withT ’s method’s return type
I Each exception thrown by the lambda body is allowed by T ’smethod’s throws clause
Lemma: There is an equivalence class of compatible target types for alambda expression.
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Functional interfaces as compatible target types
A lambda expression is compatible with a type T , if
I T is a functional interface type
I The lambda expression has the same number of parameters as T ’smethod, and those parameters’ types are the same
I Each expression returned by the lambda body is compatible withT ’s method’s return type
I Each exception thrown by the lambda body is allowed by T ’smethod’s throws clause
Lemma: There is an equivalence class of compatible target types for alambda expression.
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Canonical representative
For the equivalence class of the compatible target types of a lambdaexpression, there is a canonical representative
FunN <R,T 1, . . . ,T N>
with
interface FunN <R,T1, ..., TN >
{ R apply(T1 arg1 , ..., TN argN ); }
if the type of the single method of a compatible target type is
(T 1, . . . ,T N)→ R
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Matrices in Java 8
class Matrix extends Vector<Vector<Integer>> {//Matrix -> ((Matrix, Matrix) -> Matrix) -> Matrix
Fun1<Fun1<Matrix, Fun2<Matrix, Matrix,Matrix>>, Matrix>
op = (Matrix m) -> (Fun2<Matrix, Matrix,Matrix> f) ->
f.apply(this, m);
//(Matrix, Matrix) -> Matrix
Fun2<Matrix, Matrix,Matrix>
mul = (Matrix m1, Matrix m2) -> {Matrix ret = new Matrix ();
... //matrix multiplication
return ret; }public static void main(String[] args) {
Matrix m1 = new Matrix(...);
Matrix m2 = new Matrix(...);
(m1.op.apply(m2)).apply(m1.mul);} } }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Matrices in Java 8
class Matrix extends Vector<Vector<Integer>> {//Matrix -> ((Matrix, Matrix) -> Matrix) -> Matrix
Fun1<Fun1<Matrix, Fun2<Matrix, Matrix,Matrix>>, Matrix>
op = (Matrix m) -> (Fun2<Matrix, Matrix,Matrix> f) ->
f.apply(this, m);
//(Matrix, Matrix) -> Matrix
Fun2<Matrix, Matrix,Matrix>
mul = (Matrix m1, Matrix m2) -> {Matrix ret = new Matrix ();
... //matrix multiplication
return ret; }
public static void main(String[] args) {Matrix m1 = new Matrix(...);
Matrix m2 = new Matrix(...);
(m1.op.apply(m2)).apply(m1.mul);} } }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Matrices in Java 8
class Matrix extends Vector<Vector<Integer>> {//Matrix -> ((Matrix, Matrix) -> Matrix) -> Matrix
Fun1<Fun1<Matrix, Fun2<Matrix, Matrix,Matrix>>, Matrix>
op = (Matrix m) -> (Fun2<Matrix, Matrix,Matrix> f) ->
f.apply(this, m);
//(Matrix, Matrix) -> Matrix
Fun2<Matrix, Matrix,Matrix>
mul = (Matrix m1, Matrix m2) -> {Matrix ret = new Matrix ();
... //matrix multiplication
return ret; }public static void main(String[] args) {
Matrix m1 = new Matrix(...);
Matrix m2 = new Matrix(...);
(m1.op.apply(m2)).apply(m1.mul);} } }Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Goal
class Matrix extends Vector<Vector<Integer>> {
op = (m) -> (f) ->
f.apply(this, m);
mul = (m1, m2) -> {ret = new Matrix ();
... //matrix multiplication
return ret; }public static void main(String[] args) {
Matrix m1 = new Matrix(...);
Matrix m2 = new Matrix(...);
(m1.op.apply(m2)).apply(m1.mul);} } }Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
The language
Source := class∗class := Class(stype, [ extends( stype ), ]FieldDecl∗ )FieldDecl := Field( [type, ]var [, expr ] )block := Block( stmt∗ )stmt := block | Return( expr ) | While( bexpr , block )
| LocalVarDecl( var [, type] ) | If( bexpr , block[, block] )
| stmtexprlambdaexpr := Lambda( ((var [, type]))∗, (stmt | expr) )
stmtexpr := Assign( var , expr ) | New( stype, expr∗ )| MethodCall( iexpr , apply, expr∗ )
vexpr := LocalVar( var ) | InstVar( iexpr , var )iexpr = vexpr | stmtexpr | Cast( type, iexpr ) | this | superexpr := lambdaexpr | iexp | bexp | sexp
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
Type–inference in Java 8
I Type parameter instatiation (Java 5.0):id: a → a
id(1) : for a the type Integer is inferred.
I Diamond–operator (Java 7):Vector <Integer> v = new Vector <>
I Parameter’s type–inference in Lambda–expressions (Java 8):
(T1 x1, ..., TN xN) → h( x1 , ..., XN )
The types T1, ..., TN can be inferred:
(x1, ..., xN) → h( x1, ..., XN )
is a correct Lambda–expression in Java 8.
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Research overviewLambda–expressionsJava 8 featuresType–inference in Java 8
More type inference
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Sketch of the algorithm TI
TYPE: Introduces fresh type variables and collects the constraints
SOLVE: Solves the constraints by type unification
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Data-structures
I Set of type assumptions:
v : θ: Assumptions for fields or local variables of the actual class.τ.v : θ: Assumptions for fields of the class τ .
I Set of constraints:
{ θ R θ′ | R ∈ {l, l? ,.
= } }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Data-structures
I Set of type assumptions:
v : θ: Assumptions for fields or local variables of the actual class.τ.v : θ: Assumptions for fields of the class τ .
I Set of constraints:
{ θ R θ′ | R ∈ {l, l? ,.
= } }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TYPE: TypeAssumptions× Class→ TClass× ConstraintsSet
TYPE( Ass,Class( τ, extends( τ ′ ), fdecls ) ) =let
fdecls = [Field( f1, lexpr1 ), . . . ,Field( fn, lexprn )]ftypeass = { this.fi : ai | ai fresh type variables }
∪ { this : τ, super : τ ′ }∪ { visible types of fields of τ ′ }
AssAll = Ass ∪ ftypeassForall 16 i 6n
(lexpit : rtyFi ,ConSFi ) = TYPEExpr( AssAll , lexpri )fdeclst =
[Field( a1, f1, lexpr1t : rtyF1 ), . . . ,Field( an, fn, lexprnt : rtyFnt )]in
(Class( τ, extends( τ ′ ), fdeclst ),(⋃
i ConSFi ∪ { (rtyFi l ai ) | 16 i 6n }))
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TYPE: TypeAssumptions× Class→ TClass× ConstraintsSet
TYPE( Ass,Class( τ, extends( τ ′ ), fdecls ) ) =let
fdecls = [Field( f1, lexpr1 ), . . . ,Field( fn, lexprn )]ftypeass = { this.fi : ai | ai fresh type variables }
∪ { this : τ, super : τ ′ }∪ { visible types of fields of τ ′ }
AssAll = Ass ∪ ftypeass
Forall 16 i 6n(lexpit : rtyFi ,ConSFi ) = TYPEExpr( AssAll , lexpri )
fdeclst =[Field( a1, f1, lexpr1t : rtyF1 ), . . . ,Field( an, fn, lexprnt : rtyFnt )]
in(Class( τ, extends( τ ′ ), fdeclst ),
(⋃
i ConSFi ∪ { (rtyFi l ai ) | 16 i 6n }))
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TYPE: TypeAssumptions× Class→ TClass× ConstraintsSet
TYPE( Ass,Class( τ, extends( τ ′ ), fdecls ) ) =let
fdecls = [Field( f1, lexpr1 ), . . . ,Field( fn, lexprn )]ftypeass = { this.fi : ai | ai fresh type variables }
∪ { this : τ, super : τ ′ }∪ { visible types of fields of τ ′ }
AssAll = Ass ∪ ftypeassForall 16 i 6n
(lexpit : rtyFi ,ConSFi ) = TYPEExpr( AssAll , lexpri )
fdeclst =[Field( a1, f1, lexpr1t : rtyF1 ), . . . ,Field( an, fn, lexprnt : rtyFnt )]
in(Class( τ, extends( τ ′ ), fdeclst ),
(⋃
i ConSFi ∪ { (rtyFi l ai ) | 16 i 6n }))
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TYPE: TypeAssumptions× Class→ TClass× ConstraintsSet
TYPE( Ass,Class( τ, extends( τ ′ ), fdecls ) ) =let
fdecls = [Field( f1, lexpr1 ), . . . ,Field( fn, lexprn )]ftypeass = { this.fi : ai | ai fresh type variables }
∪ { this : τ, super : τ ′ }∪ { visible types of fields of τ ′ }
AssAll = Ass ∪ ftypeassForall 16 i 6n
(lexpit : rtyFi ,ConSFi ) = TYPEExpr( AssAll , lexpri )fdeclst =
[Field( a1, f1, lexpr1t : rtyF1 ), . . . ,Field( an, fn, lexprnt : rtyFnt )]
in(Class( τ, extends( τ ′ ), fdeclst ),
(⋃
i ConSFi ∪ { (rtyFi l ai ) | 16 i 6n }))
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TYPE: TypeAssumptions× Class→ TClass× ConstraintsSet
TYPE( Ass,Class( τ, extends( τ ′ ), fdecls ) ) =let
fdecls = [Field( f1, lexpr1 ), . . . ,Field( fn, lexprn )]ftypeass = { this.fi : ai | ai fresh type variables }
∪ { this : τ, super : τ ′ }∪ { visible types of fields of τ ′ }
AssAll = Ass ∪ ftypeassForall 16 i 6n
(lexpit : rtyFi ,ConSFi ) = TYPEExpr( AssAll , lexpri )fdeclst =
[Field( a1, f1, lexpr1t : rtyF1 ), . . . ,Field( an, fn, lexprnt : rtyFnt )]in
(Class( τ, extends( τ ′ ), fdeclst ),(⋃
i ConSFi ∪ { (rtyFi l ai ) | 16 i 6n }))
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TYPEExpr: TypeAssumptions× Expr→ TExpr× ConstraintsSet
For Lambda:
TYPEExpr( Ass, Lambda( (x1, . . . , xN), expr |stmt ) ) =let
AssArgs = { xi : ai | ai fresh type variables }(exprt : rty ,ConS) = TYPEExpr( Ass ∪ AssArgs, expr )| (stmtt : rty ,ConS) = TYPEStmt( Ass ∪ AssArgs, stmt )in
(Lambda( (x1 :a1, . . . , xN :aN), exprt : rty |stmtt : rty ): FunN <a, a1, . . . , aN>,
ConS ∪ { (rty l a) }),where a is a fresh type variable
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TYPEExpr: TypeAssumptions× Expr→ TExpr× ConstraintsSet
For Lambda:
TYPEExpr( Ass, Lambda( (x1, . . . , xN), expr |stmt ) ) =let
AssArgs = { xi : ai | ai fresh type variables }(exprt : rty ,ConS) = TYPEExpr( Ass ∪ AssArgs, expr )| (stmtt : rty ,ConS) = TYPEStmt( Ass ∪ AssArgs, stmt )in
(Lambda( (x1 :a1, . . . , xN :aN), exprt : rty |stmtt : rty ): FunN <a, a1, . . . , aN>,
ConS ∪ { (rty l a) }),where a is a fresh type variable
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
For MethodCall:
TYPEExpr( Ass,MethodCall( re, apply( e1, . . . , en ) ) ) =let
(ret : rty ,ConS) = TYPEExpr( Ass, re )(eit : rtyi ,ConSi ) = TYPEExpr( Ass, ei ),∀16 i 6n
in(MethodCall( ret : rty , apply( e1t : rty1, . . . , ent : rtyn ) ) :a,(ConS ∪
⋃i ConSi ) ∪ { rty l FunN <a, a1, . . . , aN> }
∪ { rtyi l ai | 16 i 6N }where a1, . . . , aN and a are fresh type variables
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TYPEStmt: TypeAssumptions× Stmt→ TStmt× ConstraintsSet
For Return:
TYPEStmt( Ass,Return( e ) ) =let
(et : rty ,ConS) = TYPEExpr( Ass, e )in
(Return( et : rty ) : rty ,ConS))
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TYPEStmt: TypeAssumptions× Stmt→ TStmt× ConstraintsSet
For Return:
TYPEStmt( Ass,Return( e ) ) =let
(et : rty ,ConS) = TYPEExpr( Ass, e )in
(Return( et : rty ) : rty ,ConS))
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
For Block:
TYPEStmt( Ass,Block( s ) ) =let
(st : rty ,ConS) = TYPEStmt( Ass, s )in
(Block( st : rty ) : rty ,ConS)
TYPEStmt( Ass,Block( s1, . . . , sn ) ) =let
(s1t : rty1,ConS1) = TYPEStmt( Ass, s1 )(Block( s2t , . . . , snt ) : rty2,ConS2) =
TYPEStmt( Ass,Block( s2, . . . , sn ) )in
(Block( s1t : rty1, s2t , . . . , snt ) : a,ConS1 ∪ ConS2 ∪ { (rty1 l a), (rty2 l a) })
where a is a fresh type variable
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
For Block:
TYPEStmt( Ass,Block( s ) ) =let
(st : rty ,ConS) = TYPEStmt( Ass, s )in
(Block( st : rty ) : rty ,ConS)
TYPEStmt( Ass,Block( s1, . . . , sn ) ) =let
(s1t : rty1,ConS1) = TYPEStmt( Ass, s1 )(Block( s2t , . . . , snt ) : rty2,ConS2) =
TYPEStmt( Ass,Block( s2, . . . , sn ) )in
(Block( s1t : rty1, s2t , . . . , snt ) : a,ConS1 ∪ ConS2 ∪ { (rty1 l a), (rty2 l a) })
where a is a fresh type variable
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Example
class Matrix extends Vector<Vector<Integer>> {op = (m) -> (f) -> f.apply(this, m); }
The result contains:lexpr1t =
Lam( m : am,Lam( f : af ,
MCall( LoVar( f ) : af ,apply( this : Matrix,
LoVar( m ) : am ) ) : a3 ) : Fun1<aapp, af > ) : Fun1<aλf , am>
and the set of constraint:{ (Fun1<aλf , am>l aop), (Fun1<aapp, af >l aλf ),
(af l Fun2<a3, a1, a2>), (Matrixl a1), (am l a2), (a3 l aapp) }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Example
class Matrix extends Vector<Vector<Integer>> {op = (m) -> (f) -> f.apply(this, m); }
The result contains:lexpr1t =
Lam( m : am,Lam( f : af ,
MCall( LoVar( f ) : af ,apply( this : Matrix,
LoVar( m ) : am ) ) : a3 ) : Fun1<aapp, af > ) : Fun1<aλf , am>
and the set of constraint:{ (Fun1<aλf , am>l aop), (Fun1<aapp, af >l aλf ),
(af l Fun2<a3, a1, a2>), (Matrixl a1), (am l a2), (a3 l aapp) }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Example
class Matrix extends Vector<Vector<Integer>> {op = (m) -> (f) -> f.apply(this, m); }
The result contains:lexpr1t =
Lam( m : am,Lam( f : af ,
MCall( LoVar( f ) : af ,apply( this : Matrix,
LoVar( m ) : am ) ) : a3 ) : Fun1<aapp, af > ) : Fun1<aλf , am>
and the set of constraint:{ (Fun1<aλf , am>l aop), (Fun1<aapp, af >l aλf ),
(af l Fun2<a3, a1, a2>), (Matrixl a1), (am l a2), (a3 l aapp) }Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
SOLVE: ConstraintsSet→ Constraints SubstSet ∪ { fail }
SOLVE( ConS ) =let subs = TUnify( ConS )in
if (there are σ ∈ subs in solved form) then{σ ∈ subs | σ is in solved form }
if (there are σ ∈ subs, which has the form{ v R v ′ | v , v ′are type vars }∪ { v
.= θ | v is a type vars })
then{ v R v ′ | v , v ′are type vars } ∪ { v
.= θ | v is a type vars }
else fail
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
The sub-function TUnify1
TUnify: ConstraintsSet→ { ConstraintsSet } ∪ { fail }
Input: { (θ1 l θ′1), . . . , (θn l θ′n) }
Output: {σ1, . . . , σm }
Post-condition: ∀j{ (σj( θ1 )≤∗ σj( θ′1 )), . . . , (σj( θn )≤∗ σj( θ′n )) }where ≤∗ is the sub-typing relation
1[Pluemicke 2009]: Java type unification with wildcards, INAP 07Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TI: TypeAssumptions× Class→ { (Constraints, TClass) } ∪ { fail }
TI( Ass,Class( τ, extends( τ ′ ), fdecls ) ) =let
(Class( τ, extends( τ ′ ), fdeclst ),ConS) =TYPE( Ass,Class( τ, extends( τ ′ ), fdecls ) )
{ (cs1, σ1), . . . , (csn, σn) } = SOLVE( ConS )in{ (csi , σi ( Class( τ, extends( τ ′ ), fdeclst ) )) | 16 i 6n }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
TI: TypeAssumptions× Class→ { (Constraints, TClass) } ∪ { fail }
TI( Ass,Class( τ, extends( τ ′ ), fdecls ) ) =let
(Class( τ, extends( τ ′ ), fdeclst ),ConS) =TYPE( Ass,Class( τ, extends( τ ′ ), fdecls ) )
{ (cs1, σ1), . . . , (csn, σn) } = SOLVE( ConS )in{ (csi , σi ( Class( τ, extends( τ ′ ), fdeclst ) )) | 16 i 6n }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Example
ConS = { (Fun1<aλf , am>l aop),(Fun1<aapp, af >l aλf ), (af l Fun2<a3, a1, a2>),(Matrixl a1), (am l a2), (a3 l aapp) }
The result of SOLVE (without wildcard-types):
{ ({ am l a2, a3 l aapp }∪{ aop
.= Fun1<Fun1<aapp, Fun2<a3, Matrix, a2>>, am>,
aλf.
= Fun1<aapp, Fun2<a3, Matrix, a2>>,af
.= Fun2<a3, Matrix, a2>, a1
.= Matrix })
({ am l a2, a3 l aapp }∪{ aop
.= Fun1<Fun1<aapp, Fun2<a3, Vec<Vec<Int>>, a2>>, am>,
aλf.
= Fun1<aapp, Fun2<a3, Vec<Vec<Int>>, a2>>,af
.= Fun2<a3, Vec<Vec<Int>>, a2>, a1
.= Vec<Vec<Int>> }) }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Example
ConS = { (Fun1<aλf , am>l aop),(Fun1<aapp, af >l aλf ), (af l Fun2<a3, a1, a2>),(Matrixl a1), (am l a2), (a3 l aapp) }
The result of SOLVE (without wildcard-types):
{ ({ am l a2, a3 l aapp }∪{ aop
.= Fun1<Fun1<aapp, Fun2<a3, Matrix, a2>>, am>,
aλf.
= Fun1<aapp, Fun2<a3, Matrix, a2>>,af
.= Fun2<a3, Matrix, a2>, a1
.= Matrix })
({ am l a2, a3 l aapp }∪{ aop
.= Fun1<Fun1<aapp, Fun2<a3, Vec<Vec<Int>>, a2>>, am>,
aλf.
= Fun1<aapp, Fun2<a3, Vec<Vec<Int>>, a2>>,af
.= Fun2<a3, Vec<Vec<Int>>, a2>, a1
.= Vec<Vec<Int>> }) }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Example cont.
class Matrix<a 2, a m extends a 2, a app, a 3 extends a app>
extends Vector<Vector<Integer>> {Fun1<Fun1<a app, Fun2<a 3, Matrix,a 2>>, a_m>
op = (a m m) -> (Fun2<a 3, Matrix,a 2> f) ->
f.apply(this, m); }
more principal than ...
class Matrix
extends Vector<Vector<Integer>> {Fun1<Fun1<Matrix, Fun2<Matrix, Matrix,Matrix>>, Matrix>
op = (Matrix m) -> (Fun2<Matrix, Matrix,Matrix> f) ->
f.apply(this, m); }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Example cont.
class Matrix<a 2, a m extends a 2, a app, a 3 extends a app>
extends Vector<Vector<Integer>> {Fun1<Fun1<a app, Fun2<a 3, Matrix,a 2>>, a_m>
op = (a m m) -> (Fun2<a 3, Matrix,a 2> f) ->
f.apply(this, m); }
more principal than ...
class Matrix
extends Vector<Vector<Integer>> {Fun1<Fun1<Matrix, Fun2<Matrix, Matrix,Matrix>>, Matrix>
op = (Matrix m) -> (Fun2<Matrix, Matrix,Matrix> f) ->
f.apply(this, m); }
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
The function TYPEThe function SOLVEThe whole algorithm TI
Solution of multiple results
1. Select one correct type in an Eclipse-PlugIn.⇒ standard generation of byte-code
2. Extend Java type-system by a restricted form of intersection types.⇒ a changed generation of byte-code is necessary2
2[Pluemicke 2008] ,Intersection Types in Java, PPPJ’08]Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Implementation
Java 8:
I ThisTest
I TestLambda
I Matrix (TestFunN)
Outlook: Methods
I TestMethodCall
Java 7: Overloading
I OL
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Summary and Outlook
Summary
I Complete type inference for a core of Java 8.
I Prototypical implementation
Outlook
I Methods with overloading and overriding.
I Introduction of intersection types in the code generation
Martin Plumicke Type inference in Java 8
IntroductionType inference algorithm TI
ImplementationSummary and Outlook
Summary and Outlook
Summary
I Complete type inference for a core of Java 8.
I Prototypical implementation
Outlook
I Methods with overloading and overriding.
I Introduction of intersection types in the code generation
Martin Plumicke Type inference in Java 8