Restructure. Add to Introduction and cleanup
This commit is contained in:
parent
9f088eb29d
commit
4c67504ba1
@ -125,7 +125,7 @@ m(l, v){
|
||||
\end{minipage}%
|
||||
\hfill
|
||||
\begin{minipage}{0.5\textwidth}
|
||||
\begin{lstlisting}[style=tfgj,caption=converted to A-Normal form,label=lst:anfoutput]
|
||||
\begin{lstlisting}[style=tfgj,caption=A-Normal form,label=lst:anfoutput]
|
||||
m(l, v) =
|
||||
let x1 = l in
|
||||
let x2 = v in x1.add(x2)
|
||||
@ -161,15 +161,15 @@ $
|
||||
%\hline
|
||||
\end{array}
|
||||
$
|
||||
\caption{A-Normal form}\label{fig:anf-syntax}
|
||||
\caption{Syntax of a \TamedFJ{} program in A-Normal Form}\label{fig:anf-syntax}
|
||||
\end{figure}
|
||||
|
||||
\subsection{Constraint Generation Algorithm}
|
||||
Generally subtype constraints for an expression mirror the subtype relations in the premise of the respective type rule introduced in section \ref{sec:tifj}.
|
||||
Unknown types at the time of the constraint generation step are replaced with type placeholders.
|
||||
% Generally subtype constraints for an expression mirror the subtype relations in the premise of the respective type rule introduced in section \ref{sec:tifj}.
|
||||
% Unknown types at the time of the constraint generation step are replaced with type placeholders.
|
||||
|
||||
The constraint generation step cannot determine if a capture conversion is needed for a field access or a method call.
|
||||
Those statements produce $\lessdotCC$ constraints which signal the \unify{} algorithm that they qualify for a capture conversion.
|
||||
% The constraint generation step cannot determine if a capture conversion is needed for a field access or a method call.
|
||||
% Those statements produce $\lessdotCC$ constraints which signal the \unify{} algorithm that they qualify for a capture conversion.
|
||||
|
||||
The parameter types given to a generic method also affect their return type.
|
||||
During constraint generation the algorithm does not know the parameter types yet.
|
||||
|
221
introduction.tex
221
introduction.tex
@ -10,7 +10,36 @@
|
||||
% Capture Conversion
|
||||
% Explain difference between local and global type inference
|
||||
|
||||
|
||||
% \begin{recap}\textbf{TI for FGJ without Wildcards:}
|
||||
% \TFGJ{} generates subtype constraints $(\type{T} \lessdot \type{T})$ consisting of named types and type placeholders.
|
||||
% For example the method invocation \texttt{concat(l, new Object())} generates the constraints
|
||||
% $\tv{l} \lessdot \exptype{List}{\tv{a}}, \type{Object} \lessdot \tv{a}$.
|
||||
% Subtyping without the use of wildcards is invariant \cite{FJ}:
|
||||
% Therefore the only possible solution for the type placeholder $\tv{a}$ is $\tv{a} \doteq \type{Object}$. % in Java and Featherweight Java.
|
||||
% The correct type for the variable \texttt{l} is $\exptype{List}{\type{Object}}$ (or a direct subtype).
|
||||
% %- usually the type of e must be subtypes of the method parameters
|
||||
% %- in case of a polymorphic method: type placeholders resemble type parameters
|
||||
% The type inference algorithm for Featherweight Generic Java \cite{TIforFGJ} (called \TFGJ{}) is complete and sound:
|
||||
% It is able to find a type solution for a Featherweight Generic Java program, which has no type annotations at all,
|
||||
% if there is any.
|
||||
% It's only restriction is that no polymorphic recursion is allowed.
|
||||
% \end{recap}
|
||||
|
||||
|
||||
\section{Type Inference for Java}
|
||||
- Type inference helps rapid development
|
||||
- used in Java already (var keyword)
|
||||
- keeps source code clean
|
||||
|
||||
Java comes with a local type inference algorithm
|
||||
used for lambda expressions, method calls, and the \texttt{var} keyword.
|
||||
|
||||
A type inference algorithm that is able to recreate any type annotation
|
||||
even when no type information is given at all is called a global type inference algorithm.
|
||||
The global type inference algorithm presented here is able to deal with all Java types including wildcard types.
|
||||
It can also be used for regular Java programs.
|
||||
|
||||
%The goal is to find a correct typing for a given Java program.
|
||||
Type inference for Java has many use cases and could be used to help programmers by inserting correct types for them,
|
||||
finding better type solutions for already typed Java programs (for example more generical ones),
|
||||
@ -43,9 +72,17 @@ involving a wildcard type.
|
||||
\item[Type Unification for Java with Wildcards]
|
||||
An existing unification algorithm for Java with wildcards \cite{plue09_1} states the same capabilities,
|
||||
but exposes some errors when it comes to method invocations.
|
||||
Especially the problems shown in chapter \ref{challenges} are handled incorrectly.
|
||||
The algorithm presented in this paper is able to solve all those challenges correctly
|
||||
and it's correctness is proven using a Featherweight Java calculus \cite{WildFJ}.
|
||||
Especially the challenges shown in chapter \ref{challenges} are handled incorrectly.
|
||||
The main reasons are that Plümickes algorithm only supports types which are expressible in Java syntax
|
||||
and its soundness is proven towards a self-defined subtype ordering, but never against a complete type system.
|
||||
It appears that the subtype relation changes depending on whether a type is used as an argument to a method invocation.
|
||||
We resolve this by denoting Java wildcards as existential types
|
||||
and introducing a second kind of subtype constraint. %, the current state of the art
|
||||
%and is able to deal with types that are not directly denotable in Java.
|
||||
Additionally the soundness of our algorithm is proven using a Featherweight Java calculus \cite{WildFJ}.
|
||||
|
||||
%The algorithm presented in this paper is able to solve all those challenges correctly
|
||||
%and it's correctness is proven using a Featherweight Java calculus \cite{WildFJ}.
|
||||
%But they are all correctly solved by our new type inference algorithm presented in this paper.
|
||||
|
||||
\item[Java Type Inference]
|
||||
@ -329,14 +366,16 @@ In this example we know that the type of the variable \texttt{l} is an existenti
|
||||
before being passed to a method call.
|
||||
This is done by converting the program to A-Normal form \ref{lst:addExampleLet},
|
||||
which introduces a let statement defining a new variable \texttt{v}.
|
||||
Afterwards constraints are generated \ref{lst:addExampleCons}.
|
||||
During the constraint generation step the type of the variable \texttt{v} is unknown
|
||||
and given the type placeholder $\tv{v}$.
|
||||
Afterwards unknown types are replaced by type placeholders ($\tv{v}$ for the type of \texttt{v}) and constraints are generated (see \ref{lst:addExampleCons}).
|
||||
These constraints mirror the type rules of our \TamedFJ{} calculus.
|
||||
% During the constraint generation step the type of the variable \texttt{v} is unknown
|
||||
% and given the type placeholder $\tv{v}$.
|
||||
The methodcall to \texttt{add} spawns the constraint $\tv{v} \lessdotCC \exptype{List}{\wtv{a}}$.
|
||||
Here we introduce a capture constraint ($\lessdotCC$) %a new type of subtype constraint
|
||||
expressing that the left side of the constraint is subject to a capture conversion.
|
||||
At the start of our global type inference algorithm no types are assigned yet.
|
||||
During the course of \unify{} - our unification algorithm used to solve the generated constraint set (see chapter \ref{sec:unify})- more and more types emerge.
|
||||
Now our unification algorithm \unify{} (defined in chapter \ref{sec:unify}) is used to solve these constraints.
|
||||
In the starting set of constraints no type is assigned to $\tv{v}$ yet.
|
||||
During the course of \unify{} more and more types emerge.
|
||||
As soon as a concrete type for $\tv{v}$ is given \unify{} can conduct a capture conversion if needed.
|
||||
%The constraints where this is possible are marked as capture constraints.
|
||||
In this example $\tv{v}$ will be set to $\wctype{\wildcard{X}{\type{String}}{\bot}}{List}{\rwildcard{X}}$ leaving us with the following constraints:
|
||||
@ -381,81 +420,6 @@ a type parameter to method call \texttt{<X>add(v, "String")}.
|
||||
% There are no informal parts in our \unify{} algorithm.
|
||||
% It solely consist out of transformation rules which are bound to simple checks.
|
||||
|
||||
One problem is the divergence between denotable and expressable types in Java \cite{semanticWildcardModel}.
|
||||
A wildcard in the Java syntax has no name and is bound to its enclosing type:
|
||||
$\exptype{List}{\exptype{List}{\type{?}}}$ equates to $\exptype{List}{\wctype{\rwildcard{X}}{List}{\rwildcard{X}}}$.
|
||||
During type checking \emph{intermediate types}
|
||||
%like $\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}}$
|
||||
%or $\wctype{\rwildcard{X}}{Pair}{\rwildcard{X}, \rwildcard{X}}$
|
||||
can emerge, which have no equivalent in the Java syntax.
|
||||
%Our type inference algorithm uses existential types internally but spawns type solutions compatible with Java.
|
||||
|
||||
Example: % This program is not typable with the Type Inference algorithm from Plümicke
|
||||
\begin{lstlisting}[style=java,label=shuffleExample,caption=Intermediate Types Example]
|
||||
class List<X> extends Object {...}
|
||||
class List2D<X> extends List<List<X>> {...}
|
||||
|
||||
<X> void shuffle(List<List<X>> list) {...}
|
||||
|
||||
List<List<?>> l = ...;
|
||||
List2D<?> l2d = ...;
|
||||
|
||||
shuffle(l); // Error
|
||||
shuffle(l2d); // Valid
|
||||
\end{lstlisting}
|
||||
Java is using local type inference to allow method invocations which are not describable with regular Java types.
|
||||
The \texttt{shuffle} method in this case is invoked with the type $\wctype{\rwildcard{X}}{List2D}{\rwildcard{X}}$
|
||||
which is a subtype of $\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}}$.
|
||||
After capture conversion \texttt{l2d'} has the type $\exptype{List}{\exptype{List}{\rwildcard{X}}}$
|
||||
and \texttt{shuffle} can be invoked with the type parameter $\rwildcard{X}$:
|
||||
\begin{lstlisting}[style=TamedFJ]
|
||||
let l2d' : (*@$\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}}$@*) = l2d in <X>shuffle(l2d')
|
||||
\end{lstlisting}
|
||||
|
||||
\begin{recap}\textbf{TI for FGJ without Wildcards:}
|
||||
\TFGJ{} generates subtype constraints $(\type{T} \lessdot \type{T})$ consisting of named types and type placeholders.
|
||||
For example the method invocation \texttt{concat(l, new Object())} generates the constraints
|
||||
$\tv{l} \lessdot \exptype{List}{\tv{a}}, \type{Object} \lessdot \tv{a}$.
|
||||
Subtyping without the use of wildcards is invariant \cite{FJ}:
|
||||
Therefore the only possible solution for the type placeholder $\tv{a}$ is $\tv{a} \doteq \type{Object}$. % in Java and Featherweight Java.
|
||||
The correct type for the variable \texttt{l} is $\exptype{List}{\type{Object}}$ (or a direct subtype).
|
||||
%- usually the type of e must be subtypes of the method parameters
|
||||
%- in case of a polymorphic method: type placeholders resemble type parameters
|
||||
The type inference algorithm for Featherweight Generic Java \cite{TIforFGJ} (called \TFGJ{}) is complete and sound:
|
||||
It is able to find a type solution for a Featherweight Generic Java program, which has no type annotations at all,
|
||||
if there is any.
|
||||
It's only restriction is that no polymorphic recursion is allowed.
|
||||
\end{recap}
|
||||
%
|
||||
|
||||
For the example shown in listing \ref{shuffleExample} the method call \texttt{shuffle(l2d)} creates the constraints:
|
||||
\begin{constraintset}
|
||||
\begin{center}
|
||||
$
|
||||
\begin{array}{l}
|
||||
\wctype{\rwildcard{X}}{List2D}{\rwildcard{X}} \lessdotCC \exptype{List}{\exptype{List}{\wtv{x}}}
|
||||
\\
|
||||
\hline
|
||||
\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}} \lessdotCC \exptype{List}{\exptype{List}{\wtv{x}}}
|
||||
\\
|
||||
\hline
|
||||
\textit{Capture Conversion:}\
|
||||
\exptype{List}{\exptype{List}{\rwildcard{X}}} \lessdot \exptype{List}{\exptype{List}{\wtv{x}}}
|
||||
\\
|
||||
\hline
|
||||
\textit{Solution:} \wtv{x} \doteq \rwildcard{X} \implies \exptype{List}{\exptype{List}{\rwildcard{X}}} \lessdot \exptype{List}{\exptype{List}{\rwildcard{X}}}
|
||||
\end{array}
|
||||
$
|
||||
\end{center}
|
||||
\end{constraintset}
|
||||
|
||||
The method call \texttt{shuffle(l)} is invalid however,
|
||||
because \texttt{l} has the type
|
||||
$\exptype{List}{\wctype{\rwildcard{X}}{List}{\rwildcard{X}}}$.
|
||||
There is no solution for the subtype constraint:
|
||||
$\exptype{List}{\wctype{\rwildcard{X}}{List}{\rwildcard{X}}} \lessdotCC \exptype{List}{\exptype{List}{\wtv{x}}}$
|
||||
|
||||
|
||||
\subsection{Challenges}\label{challenges}
|
||||
%TODO: Wildcard subtyping is infinite see \cite{TamingWildcards}
|
||||
|
||||
@ -486,28 +450,79 @@ exists to satisfy
|
||||
$\exptype{List}{\type{A}} <: \exptype{List}{\type{X}},
|
||||
\exptype{List}{\type{A}} <: \exptype{List}{\type{Y}}$.
|
||||
|
||||
% \item
|
||||
% \unify{} morphs a constraint set into a correct type solution
|
||||
% gradually assigning types to type placeholders during that process.
|
||||
% Solved constraints are removed and never considered again.
|
||||
% In the following example \unify{} solves the constraint generated by the expression
|
||||
% \texttt{l.add(l.head())} first, which results in $\ntv{l} \lessdot \exptype{List}{\wtv{a}}$.
|
||||
% \begin{verbatim}
|
||||
% anyList() = new List<String>() :? new List<Integer>()
|
||||
\item
|
||||
\unify{} morphs a constraint set into a correct type solution
|
||||
gradually assigning types to type placeholders during that process.
|
||||
Solved constraints are removed and never considered again.
|
||||
In the following example \unify{} solves the constraint generated by the expression
|
||||
\texttt{l.add(l.head())} first, which results in $\ntv{l} \lessdot \exptype{List}{\wtv{a}}$.
|
||||
\begin{verbatim}
|
||||
anyList() = new List<String>() :? new List<Integer>()
|
||||
|
||||
% add(anyList(), anyList().head());
|
||||
% \end{verbatim}
|
||||
% The type for \texttt{l} can be any kind of list, but it has to be a invariant one.
|
||||
% Assigning a \texttt{List<?>} for \texttt{l} is unsound, because the type list hiding behind
|
||||
% \texttt{List<?>} could be a different one for the \texttt{add} call than the \texttt{head} method call.
|
||||
% An additional constraint $\wctype{\rwildcard{X}}{List}{\rwildcard{X}} \lessdot \exptype{List}{\wtv{a}}$
|
||||
% is solved by removing the wildcard $\rwildcard{X}$ if possible.
|
||||
add(anyList(), anyList().head());
|
||||
\end{verbatim}
|
||||
The type for \texttt{l} can be any kind of list, but it has to be a invariant one.
|
||||
Assigning a \texttt{List<?>} for \texttt{l} is unsound, because the type list hiding behind
|
||||
\texttt{List<?>} could be a different one for the \texttt{add} call than the \texttt{head} method call.
|
||||
An additional constraint $\wctype{\rwildcard{X}}{List}{\rwildcard{X}} \lessdot \exptype{List}{\wtv{a}}$
|
||||
is solved by removing the wildcard $\rwildcard{X}$ if possible.
|
||||
|
||||
\item \textbf{Capture Conversion during \unify{}:}
|
||||
The example in \ref{lst:addExample} needs to be solvable.
|
||||
Here a capture conversion during the unification step of our algorithm has to be conducted.
|
||||
Otherwise the \texttt{add} method is not callable with the existential type
|
||||
$\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}}$.
|
||||
this problem is solved by ANF transformation
|
||||
|
||||
\item \textbf{Wildcards as Existential Types:}
|
||||
One problem is the divergence between denotable and expressable types in Java \cite{semanticWildcardModel}.
|
||||
A wildcard in the Java syntax has no name and is bound to its enclosing type:
|
||||
$\exptype{List}{\exptype{List}{\type{?}}}$ equates to $\exptype{List}{\wctype{\rwildcard{X}}{List}{\rwildcard{X}}}$.
|
||||
During type checking \emph{intermediate types}
|
||||
can emerge, which have no equivalent in the Java syntax.
|
||||
|
||||
\begin{lstlisting}[style=java,label=shuffleExample,caption=Intermediate Types Example]
|
||||
class List<X> extends Object {...}
|
||||
class List2D<X> extends List<List<X>> {...}
|
||||
|
||||
<X> void shuffle(List<List<X>> list) {...}
|
||||
|
||||
List<List<?>> l = ...;
|
||||
List2D<?> l2d = ...;
|
||||
|
||||
shuffle(l); // Error
|
||||
shuffle(l2d); // Valid
|
||||
\end{lstlisting}
|
||||
Java is using local type inference to allow method invocations which are not describable with regular Java types.
|
||||
The \texttt{shuffle} method in this case is invoked with the type $\wctype{\rwildcard{X}}{List2D}{\rwildcard{X}}$
|
||||
which is a subtype of $\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}}$.
|
||||
After capture conversion \texttt{l2d'} has the type $\exptype{List}{\exptype{List}{\rwildcard{X}}}$
|
||||
and \texttt{shuffle} can be invoked with the type parameter $\rwildcard{X}$:
|
||||
\begin{lstlisting}[style=TamedFJ]
|
||||
let l2d' : (*@$\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}}$@*) = l2d in <X>shuffle(l2d')
|
||||
\end{lstlisting}
|
||||
|
||||
For the example shown in listing \ref{shuffleExample} the method call \texttt{shuffle(l2d)} creates the constraints:
|
||||
\begin{constraintset}
|
||||
\begin{center}
|
||||
$
|
||||
\begin{array}{l}
|
||||
\wctype{\rwildcard{X}}{List2D}{\rwildcard{X}} \lessdotCC \exptype{List}{\exptype{List}{\wtv{x}}}
|
||||
\\
|
||||
\hline
|
||||
\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}} \lessdotCC \exptype{List}{\exptype{List}{\wtv{x}}}
|
||||
\\
|
||||
\hline
|
||||
\textit{Capture Conversion:}\
|
||||
\exptype{List}{\exptype{List}{\rwildcard{X}}} \lessdot \exptype{List}{\exptype{List}{\wtv{x}}}
|
||||
\\
|
||||
\hline
|
||||
\textit{Solution:} \wtv{x} \doteq \rwildcard{X} \implies \exptype{List}{\exptype{List}{\rwildcard{X}}} \lessdot \exptype{List}{\exptype{List}{\rwildcard{X}}}
|
||||
\end{array}
|
||||
$
|
||||
\end{center}
|
||||
\end{constraintset}
|
||||
|
||||
The method call \texttt{shuffle(l)} is invalid however,
|
||||
because \texttt{l} has the type
|
||||
$\exptype{List}{\wctype{\rwildcard{X}}{List}{\rwildcard{X}}}$.
|
||||
There is no solution for the subtype constraint:
|
||||
$\exptype{List}{\wctype{\rwildcard{X}}{List}{\rwildcard{X}}} \lessdotCC \exptype{List}{\exptype{List}{\wtv{x}}}$
|
||||
|
||||
\item \textbf{Free Variables cannot leaver their scope}:
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user