add shuffle example to wildcard introduction
This commit is contained in:
parent
cbba453a73
commit
4547fbab40
113
introduction.tex
113
introduction.tex
@ -23,6 +23,9 @@ resulting in a correctly typed program (see figure \ref{fig:nested-list-example-
|
|||||||
|
|
||||||
\begin{itemize}
|
\begin{itemize}
|
||||||
\item
|
\item
|
||||||
|
We introduce the language \tifj{} (chapter \ref{sec:tifj}).
|
||||||
|
A Featherweight Java derivative including Generics, Wildcards and Type Inference.
|
||||||
|
\item
|
||||||
We support capture conversion and Java style method calls.
|
We support capture conversion and Java style method calls.
|
||||||
This requires existential types in a form which is not denotable by Java syntax \cite{aModelForJavaWithWildcards}.
|
This requires existential types in a form which is not denotable by Java syntax \cite{aModelForJavaWithWildcards}.
|
||||||
\item
|
\item
|
||||||
@ -171,8 +174,6 @@ Wildcards can be formalized as existential types \cite{WildFJ}.
|
|||||||
denoted in our syntax by $\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$ and
|
denoted in our syntax by $\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$ and
|
||||||
$\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}}$.
|
$\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}}$.
|
||||||
|
|
||||||
$\exptype{List}{String} <: \wctype{\wildcard{X}{\bot}{\type{Object}}}{List}{\rwildcard{X}}$
|
|
||||||
means \texttt{List<String>} is a subtype of \texttt{List<? extend Object>}.
|
|
||||||
The syntax used here allows for wildcard parameters to have a name, an uppper and lower bound at the same time,
|
The syntax used here allows for wildcard parameters to have a name, an uppper and lower bound at the same time,
|
||||||
and a type they are bound to.
|
and a type they are bound to.
|
||||||
In this case the name is $\rwildcard{X}$ and it's bound to the the type \texttt{List}.
|
In this case the name is $\rwildcard{X}$ and it's bound to the the type \texttt{List}.
|
||||||
@ -180,17 +181,69 @@ In this case the name is $\rwildcard{X}$ and it's bound to the the type \texttt{
|
|||||||
Those properties are needed to formalize capture conversion.
|
Those properties are needed to formalize capture conversion.
|
||||||
Polymorphic method calls need to be wraped in a process which \textit{opens} existential types \cite{addingWildcardsToJava}.
|
Polymorphic method calls need to be wraped in a process which \textit{opens} existential types \cite{addingWildcardsToJava}.
|
||||||
In Java this is done implicitly in a process called capture conversion.
|
In Java this is done implicitly in a process called capture conversion.
|
||||||
% When calling a polymorphic method like \texttt{<X> List<X> m(List<X> l1, List<X> l2)} with a \texttt{List<?>}
|
|
||||||
% it is not possible to substitute \texttt{?} for \texttt{X}.
|
One problem is the divergence between denotable and expressable types in Java \cite{semanticWildcardModel}.
|
||||||
% This would lead to the method header \texttt{List<?> m(List<?> l1, List<?> l2)}
|
A wildcard in the Java syntax has no name and is bound to its enclosing type.
|
||||||
% where now a method invocation with \texttt{List<String>} and \texttt{List<Integer>} would be possible,
|
$\exptype{List}{\exptype{List}{\type{?}}}$ equates to $\exptype{List}{\wctype{\rwildcard{X}}{List}{\rwildcard{X}}}$.
|
||||||
% because both are subtypes of \texttt{List<?>}.
|
During type checking \emph{intermediate types}
|
||||||
% Capture conversion solves this problem by generating a fresh type variable for every wildcard.
|
%like $\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}}$
|
||||||
% Calling \texttt{<X> X head(List<X> l1)} with the type \texttt{List<?>} ($\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$)
|
%or $\wctype{\rwildcard{X}}{Pair}{\rwildcard{X}, \rwildcard{X}}$
|
||||||
% creates a fresh type variable $\rwildcard{Y}$ resulting in
|
can emerge, which have no equivalent in the Java syntax.
|
||||||
% $\generics{\rwildcard{Y}}\texttt{head}(\exptype{List}{\rwildcard{Y}})$
|
%Our type inference algorithm uses existential types internally but spawns type solutions compatible with Java.
|
||||||
% with $\rwildcard{Y}$ being used as generic parameter \texttt{X}.
|
|
||||||
% The $\rwildcard{Y}$ in $\exptype{List}{\rwildcard{Y}}$ is a free variable now.
|
Example: % This program is not typable with the Type Inference algorithm from Plümicke
|
||||||
|
\begin{verbatim}
|
||||||
|
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{verbatim}
|
||||||
|
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=letfj]
|
||||||
|
let l2d' : (*@$\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}}$@*) = l2d in <X>shuffle(l2d')
|
||||||
|
\end{lstlisting}
|
||||||
|
|
||||||
|
The respective constraints are:
|
||||||
|
\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}
|
||||||
|
|
||||||
|
\texttt{l} however has the type
|
||||||
|
$\exptype{List}{\wctype{\rwildcard{X}}{List}{\rwildcard{X}}}$.
|
||||||
|
The method call \texttt{shuffle(l)} is not correct, because there is no solution for the subtype constraint:
|
||||||
|
|
||||||
|
$\exptype{List}{\wctype{\rwildcard{X}}{List}{\rwildcard{X}}} \lessdotCC \exptype{List}{\exptype{List}{\wtv{x}}}$
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
% $\exptype{List}{String} <: \wctype{\wildcard{X}{\bot}{\type{Object}}}{List}{\rwildcard{X}}$
|
||||||
|
% means \texttt{List<String>} is a subtype of \texttt{List<? extend Object>}.
|
||||||
|
|
||||||
\subsection{Global Type Inference}
|
\subsection{Global Type Inference}
|
||||||
% A global type inference algorithm works on an input with no type annotations at all.
|
% A global type inference algorithm works on an input with no type annotations at all.
|
||||||
@ -202,20 +255,25 @@ In Java this is done implicitly in a process called capture conversion.
|
|||||||
|
|
||||||
% $\tv{l} \lessdotCC \exptype{List}{\wtv{x}}, \tv{l} \lessdotCC \wtv{x}$
|
% $\tv{l} \lessdotCC \exptype{List}{\wtv{x}}, \tv{l} \lessdotCC \wtv{x}$
|
||||||
|
|
||||||
The input to our type inference algorithm is a modified version of the \letfj{} calculus presented in \cite{WildcardsNeedWitnessProtection}.
|
\begin{description}
|
||||||
\fjtype{} generates constraints from an input program and is the first step of the algorithm.
|
\item[input] \tifj{} program
|
||||||
Afterwards \unify{} computes a solution for the given constraint set.
|
\item[output] type solution
|
||||||
|
\item[postcondition] the type solution applied to the input must yield a valid \letfj{} program
|
||||||
|
\end{description}
|
||||||
|
|
||||||
|
The input to our type inference algorithm is a modified version of the \letfj{}\cite{WildcardsNeedWitnessProtection} calculus (see chapter \ref{sec:tifj}).
|
||||||
|
First \fjtype{} generates constraints
|
||||||
|
and afterwards \unify{} computes a solution for the given constraint set.
|
||||||
Constraints consist out of subtype constraints $(\type{T} \lessdot \type{T})$ and capture constraints $(\type{T} \lessdotCC \type{T})$.
|
Constraints consist out of subtype constraints $(\type{T} \lessdot \type{T})$ and capture constraints $(\type{T} \lessdotCC \type{T})$.
|
||||||
Additionally to types constraints can also hold type placeholders $\ntv{a}$ and wildcard type placeholders $\wtv{a}$.
|
\textit{Note:} a type $\type{T}$ can also be a type placeholders $\ntv{a}$ or a wildcard type placeholder $\wtv{a}$.
|
||||||
A subtype constraint is satisfied if the left side is a subtype of the right side according to the rules in figure \ref{fig:subtyping}.
|
A subtype constraint is satisfied if the left side is a subtype of the right side according to the rules in figure \ref{fig:subtyping}.
|
||||||
\textit{Example:} $\exptype{List}{\tv{a}} \lessdot \exptype{List}{\type{String}}$ is fulfilled by replacing type placeholder $\tv{a}$ with the type $\type{String}$.
|
\textit{Example:} $\exptype{List}{\ntv{a}} \lessdot \exptype{List}{\type{String}}$ is fulfilled by replacing type placeholder $\ntv{a}$ with the type $\type{String}$.
|
||||||
Subtype constraints and type placeholders act the same as the ones used in \emph{Type Inference for Featherweight Generic Java} \cite{TIforGFJ}.
|
Subtype constraints and type placeholders act the same as the ones used in \emph{Type Inference for Featherweight Generic Java} \cite{TIforFGJ}.
|
||||||
The novel capture constraints and wildcard placeholders are needed for method invocations involving wildcards.
|
The novel capture constraints and wildcard placeholders are needed for method invocations involving wildcards.
|
||||||
|
|
||||||
%show input and a correct letFJ representation
|
%show input and a correct letFJ representation
|
||||||
Even in a full typed program local type inference can be necessary.
|
Even in a full typed program local type inference can be necessary.
|
||||||
%TODO: first show local type inference and explain lessdotCC constraints. then show example with global TI
|
%TODO: first show local type inference and explain lessdotCC constraints. then show example with global TI
|
||||||
Our algorithm has to find a type solution and a \letfj{} representation for a given input program.
|
|
||||||
Let's start with an example where all types are already given:
|
Let's start with an example where all types are already given:
|
||||||
\begin{lstlisting}[style=tfgj, caption=Valid Java program, label=lst:addExample]
|
\begin{lstlisting}[style=tfgj, caption=Valid Java program, label=lst:addExample]
|
||||||
<A> List<A> add(List<A> l, A v)
|
<A> List<A> add(List<A> l, A v)
|
||||||
@ -238,16 +296,18 @@ Our type inference algorithm has to add let statements if necessary, including t
|
|||||||
|
|
||||||
Lets have a look at the constraints generated by \fjtype{} for the example in listing \ref{lst:addExample}:
|
Lets have a look at the constraints generated by \fjtype{} for the example in listing \ref{lst:addExample}:
|
||||||
\begin{constraintset}
|
\begin{constraintset}
|
||||||
$\begin{array}{l}
|
\begin{center}
|
||||||
|
$\begin{array}{c}
|
||||||
\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}} \lessdotCC \exptype{List}{\wtv{a}}, \, \type{String} \lessdotCC \wtv{a}
|
\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}} \lessdotCC \exptype{List}{\wtv{a}}, \, \type{String} \lessdotCC \wtv{a}
|
||||||
\\
|
\\
|
||||||
\hline
|
\hline
|
||||||
\text{Capture Conversion:}\ \exptype{List}{\rwildcard{X}} \lessdot \exptype{List}{\wtv{a}}, \, \type{String} \lessdot \wtv{a}
|
\textit{Capture Conversion:}\ \exptype{List}{\rwildcard{X}} \lessdot \exptype{List}{\wtv{a}}, \, \type{String} \lessdot \wtv{a}
|
||||||
\\
|
\\
|
||||||
\hline
|
\hline
|
||||||
\text{Solution:}\ \wtv{a} \doteq \rwildcard{X} \implies \exptype{List}{\rwildcard{X}} \lessdot \exptype{List}{\rwildcard{X}}, \, \type{String} \lessdot \rwildcard{X}
|
\textit{Solution:}\ \wtv{a} \doteq \rwildcard{X} \implies \exptype{List}{\rwildcard{X}} \lessdot \exptype{List}{\rwildcard{X}}, \, \type{String} \lessdot \rwildcard{X}
|
||||||
\end{array}
|
\end{array}
|
||||||
$
|
$
|
||||||
|
\end{center}
|
||||||
\end{constraintset}
|
\end{constraintset}
|
||||||
%Why do we need the lessdotCC constraints here?
|
%Why do we need the lessdotCC constraints here?
|
||||||
The type of \texttt{l} can be capture converted by a let statement if needed (see listing \ref{lst:addExampleLet}).
|
The type of \texttt{l} can be capture converted by a let statement if needed (see listing \ref{lst:addExampleLet}).
|
||||||
@ -307,13 +367,6 @@ List<?> m() = new List<String>() :? new List<Integer>() :? id(m());
|
|||||||
\subsection{Challenges}\label{challenges}
|
\subsection{Challenges}\label{challenges}
|
||||||
%TODO: Wildcard subtyping is infinite see \cite{TamingWildcards}
|
%TODO: Wildcard subtyping is infinite see \cite{TamingWildcards}
|
||||||
|
|
||||||
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.
|
|
||||||
|
|
||||||
|
|
||||||
The introduction of wildcards adds additional challenges.
|
The introduction of wildcards adds additional challenges.
|
||||||
% we cannot replace every type variable with a wildcard
|
% we cannot replace every type variable with a wildcard
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
\lstdefinestyle{tfgj}{backgroundcolor=\color{lightgray!20}}
|
\lstdefinestyle{tfgj}{backgroundcolor=\color{lightgray!20}}
|
||||||
\lstdefinestyle{letfj}{backgroundcolor=\color{lightgray!20}}
|
\lstdefinestyle{letfj}{backgroundcolor=\color{lightgray!20}}
|
||||||
|
|
||||||
|
\newcommand{\tifj}{\texttt{TamedFJ}}
|
||||||
|
|
||||||
\newcommand\mv[1]{{\tt #1}}
|
\newcommand\mv[1]{{\tt #1}}
|
||||||
\newcommand{\ol}[1]{\overline{\tt #1}}
|
\newcommand{\ol}[1]{\overline{\tt #1}}
|
||||||
@ -113,7 +114,8 @@
|
|||||||
\newcommand{\wtypestore}[3]{\ensuremath{#1 = \wtype{#2}{#3}}}
|
\newcommand{\wtypestore}[3]{\ensuremath{#1 = \wtype{#2}{#3}}}
|
||||||
%\newcommand{\wtype}[2]{\ensuremath{[#1\ #2]}}
|
%\newcommand{\wtype}[2]{\ensuremath{[#1\ #2]}}
|
||||||
\newcommand{\wtv}[1]{\ensuremath{\tv{#1}_?}}
|
\newcommand{\wtv}[1]{\ensuremath{\tv{#1}_?}}
|
||||||
\newcommand{\ntv}[1]{\ensuremath{\underline{\tv{#1}}}}
|
%\newcommand{\ntv}[1]{\ensuremath{\underline{\tv{#1}}}}
|
||||||
|
\newcommand{\ntv}[1]{\tv{#1}}
|
||||||
\newcommand{\wcstore}{\ensuremath{\Delta}}
|
\newcommand{\wcstore}{\ensuremath{\Delta}}
|
||||||
|
|
||||||
%\newcommand{\rwildcard}[1]{\ensuremath{\mathtt{#1}_?}}
|
%\newcommand{\rwildcard}[1]{\ensuremath{\mathtt{#1}_?}}
|
||||||
|
12
tRules.tex
12
tRules.tex
@ -1,4 +1,4 @@
|
|||||||
\section{Syntax and Typing}
|
\section{Syntax and Typing}\label{sec:tifj}
|
||||||
|
|
||||||
The input syntax for our algorithm is shown in figure \ref{fig:syntax}
|
The input syntax for our algorithm is shown in figure \ref{fig:syntax}
|
||||||
and the respective type rules in figure \ref{fig:expressionTyping} and \ref{fig:typing}.
|
and the respective type rules in figure \ref{fig:expressionTyping} and \ref{fig:typing}.
|
||||||
@ -8,6 +8,16 @@ The input language is designed to showcase type inference involving existential
|
|||||||
Method call rule T-Call is the most interesting part, because it emulates the behaviour of a Java method call,
|
Method call rule T-Call is the most interesting part, because it emulates the behaviour of a Java method call,
|
||||||
where existential types are implicitly \textit{opened} and \textit{closed}.
|
where existential types are implicitly \textit{opened} and \textit{closed}.
|
||||||
|
|
||||||
|
Example: %TODO
|
||||||
|
\begin{verbatim}
|
||||||
|
class List<A> {
|
||||||
|
A head;
|
||||||
|
List<A> tail;
|
||||||
|
|
||||||
|
add(v) = new List(v, this);
|
||||||
|
}
|
||||||
|
\end{verbatim}
|
||||||
|
|
||||||
%The T-Elvis rule mimics the type judgement of a branch expression like \texttt{if-else}.
|
%The T-Elvis rule mimics the type judgement of a branch expression like \texttt{if-else}.
|
||||||
%and is solely used for examples.
|
%and is solely used for examples.
|
||||||
The calculus does not include method overriding for simplicity reasons.
|
The calculus does not include method overriding for simplicity reasons.
|
||||||
|
Loading…
Reference in New Issue
Block a user