Change Introductin Layout

This commit is contained in:
JanUlrich 2024-05-08 16:57:58 +02:00
parent 2dae79053c
commit 3a7c862fd2
2 changed files with 83 additions and 99 deletions

View File

@ -10,12 +10,12 @@
% Capture Conversion
% Explain difference between local and global type inference
someList(){}
concat(l1, l2){
return l1.add(l2)
}
\section{Global Type Inference}
Java already provides type inference in a restricted form namely local type inference.
It takes a vital role in method invocations
by determining type parameters.
%TODO: Explain Java needs it for capture conversion
\section{Motivation}
Java already uses type inference when it comes to method invocations, local variables or lambda expressions.
The crucial part for all of this use cases is the surrounding context.
The invocation of \texttt{emptyList} missing type parameters can be added by Java's local type inference
@ -310,19 +310,21 @@ if not for the Java type system which rejects the assignment \texttt{lo = ls}.
Listing \ref{lst:wildcardIntro} shows the use of wildcards rendering the assignment \texttt{lo = ls} correct.
The program still does not compile, because now the addition of an Integer to \texttt{lo} is rightfully deemed incorrect by Java.
This behaviour is emulated by our language \TamedFJ{}.
A Featherweight Java \cite{FJ} derivative with added wildcard support
and a global type inference feature.
\TamedFJ{} is basically the language described by \textit{Bierhoff} \cite{WildcardsNeedWitnessProtection} with optional type annotations.
Let's have a look at a representation of the \texttt{add} call from the last line in listing \ref{lst:wildcardIntro} in our calculus:
% Goal: Motivate the TamedFJ language. Why do we need it (Capture Conversion)
This behaviour is emulated by our language \TamedFJ{},
a Featherweight Java \cite{FJ} derivative with added wildcard support
and a global type inference feature (syntax definition in section \ref{sec:tifj}).
%\TamedFJ{} is basically the language described by \textit{Bierhoff} \cite{WildcardsNeedWitnessProtection} with optional type annotations.
Let's have a look at a representation of the \texttt{add} call from the last line in listing \ref{lst:wildcardIntro} with our calculus \TamedFJ{}:
%The \texttt{add} call in listing \ref{lst:wildcardIntro} needs to be encased by a \texttt{let} statement in our calculus.
%This makes the capture converion explicit.
\begin{lstlisting}
let v : (*@$\wctype{\wildcard{A}{\type{Object}}{\bot}}{List}{\rwildcard{A}}$@*) = lo in v.<A>add(new Integer(1));
\end{lstlisting}
The method call needs to be encased in a \texttt{let} statement.
The variable \expr{v} is assigned the \textbf{Existential Type} $\wctype{\wildcard{A}{\type{Object}}{\bot}}{List}{\rwildcard{A}}$.
Wildcards can be formalized as existential types \cite{WildFJ}:
The method call is encased in a \texttt{let} statement and
\expr{lo} is assigned to a new variable \expr{v} of \linebreak[2]
\textbf{Existential Type} $\wctype{\wildcard{A}{\type{Object}}{\bot}}{List}{\rwildcard{A}}$.
Our calculus uses existential types \cite{WildFJ} to formalize wildcards:
\texttt{List<? extends Object>} is translated to $\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$
and \texttt{List<? super String>} is expressed as $\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}}$.
The syntax used here allows for wildcard parameters to have a name, an uppper and lower bound,
@ -330,29 +332,16 @@ and a type they are bound to.
In this case the name is $\rwildcard{A}$ and it's bound to the the type \texttt{List}.
Inside the \texttt{let} statement the variable \expr{v} has the type
$\exptype{List}{\rwildcard{A}}$.
This is an explicit version of \textbf{Capture Conversion},
This is an explicit version of \linebreak[2]
\textbf{Capture Conversion},
which makes use of the fact that a concrete type must be behind every wildcard type.
There is no instantiation of a \texttt{List<?>},
but there exists some unknown type $\exptype{List}{\rwildcard{A}}$, with $\rwildcard{A}$ inbetween the bounds $\bot$ (bottom type, subtype of all types) and
\texttt{Object}.
After assigning \texttt{lo} to \expr{v} it will not change it's type during the execution of the body of \texttt{let}
and \expr{v} is treated as the type $\exptype{List}{\rwildcard{A}}$
\begin{displaymath}
\begin{array}{l}
\begin{array}{@{}c}
\textit{mtype}(\texttt{concat}) = \generics{\type{X}}\ \exptype{List}{\type{X}} \to \exptype{List}{\type{X}} \to \exptype{List}{\type{X}} \\
\texttt{l1} : \wctype{\rwildcard{A}}{List}{\rwildcard{A}}, \texttt{l2} : \wctype{\rwildcard{B}}{List}{\rwildcard{B}} \\
\exptype{List}{\rwildcard{A}} \nless: [{\color{red}?}/\type{X}]\exptype{List}{\type{X}} \quad \quad
\exptype{List}{\rwildcard{B}} \nless: [{\color{red}?}/\type{X}]\exptype{List}{\type{X}}
\\
\hline
\vspace*{-0.3cm}\\
\texttt{concat}(\expr{l1}, \expr{l2}) : {\color{red}\textbf{Error}}
\end{array}
\end{array}
\end{displaymath}
Inside the body of the let statement \expr{v} is treated as a value with the constant type $\exptype{List}{\rwildcard{A}}$.
Existential types enable us to formalize \textit{Capture Conversion}.
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.
\begin{figure}
\begin{minipage}{0.4\textwidth}
@ -374,73 +363,10 @@ lo.add(new Integer(1)); // error!
\end{minipage}
\end{figure}
\begin{recap}{\textbf{Capture Conversion}}
TODO %Explain Java Capture Conversion
%Passing wildcard types to a polymorphic method call comes with additional challenges.
% TODO: Here the concat example!
%- Wildcards are not reflexive
%- Wildcards are opaque types. Behind a Java Wildcard is a real type.
Wildcard types are virtual types.
There is no instantiation of a \texttt{List<?>}.
It is a placeholder type which can hold any kind of list like
\texttt{List<String>} or \texttt{List<Object>}.
This type can also change at any given time, for example when multiple threads
are using the same field of type \texttt{List<?>}.
A wildcard \texttt{?} must be considered a different type everytime it is accessed.
Therefore calling the method \texttt{concat} with two wildcard lists in the example in listing \ref{lst:concatError} is incorrect.
The \texttt{concat} method does not create a new list,
but adds all elements from the second argument to the list given as the first argument.
This is allowed in Java, because both lists are of the polymorphic type \texttt{List<X>}.
As shown in listing \ref{lst:concatError} this leads to a inconsistent \texttt{List<String>}
if Java would treat \texttt{?} as a regular type and instantiate the type variable \texttt{X}
of the \texttt{concat} function with \texttt{?}.
To enable the use of wildcards in argument types of a method invocation
Java uses a process called \textit{Capture Conversion}.
\begin{lstlisting}[caption=Concat Example,label=lst:concatError]{java}
<X> List<X> concat(List<X> l1, List<X> l2){
return l1.addAll(l2);
}
List<String> ls = new List<String>();
List<?> l1 = ls;
List<?> l2 = new List<Integer>(1);
concat(l1, l2);
\end{lstlisting}
%Existential types enable us to formalize Java's method call behavior and the so called Capture Conversion.
\begin{displaymath}
%TODO:
\begin{array}{l}
\begin{array}{@{}c}
\textit{mtype}(\texttt{concat}) = \generics{\type{X}}\ \exptype{List}{\type{X}} \to \exptype{List}{\type{X}} \to \exptype{List}{\type{X}} \\
\texttt{l1} : \wctype{\rwildcard{A}}{List}{\rwildcard{A}}, \texttt{l2} : \wctype{\rwildcard{B}}{List}{\rwildcard{B}} \\
\exptype{List}{\rwildcard{A}} \nless: [{\color{red}?}/\type{X}]\exptype{List}{\type{X}} \quad \quad
\exptype{List}{\rwildcard{B}} \nless: [{\color{red}?}/\type{X}]\exptype{List}{\type{X}}
\\
\hline
\vspace*{-0.3cm}\\
\texttt{concat}(\expr{l1}, \expr{l2}) : {\color{red}\textbf{Errror}}
\end{array}
\end{array}
\end{displaymath}
%A method call in Java makes use of the fact that a real type is behind a wildcard type
Wildcards can be formalized as existential types \cite{WildFJ}.
A \texttt{List<? extends Object>} is translated to $\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$
and \texttt{List<? super String>} is expressed as $\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}}$.
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.
In this case the name is $\rwildcard{X}$ and it's bound to the the type \texttt{List}.
Using existential types to express Java's wildcard types enables us to formalize \textit{Capture Conversion}.
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.
\end{recap}
%show input and a correct letFJ representation
%TODO: first show local type inference and explain lessdotCC constraints. then show example with global TI
@ -726,8 +652,64 @@ A problem arises when replacing type variables with wildcards.
% do not substitute free type variables
Lets have a look at two examples:
Lets have a look at a few challenges:
\begin{itemize}
\item
%Passing wildcard types to a polymorphic method call comes with additional challenges.
% TODO: Here the concat example!
%- Wildcards are not reflexive
%- Wildcards are opaque types. Behind a Java Wildcard is a real type.
Wildcard types are virtual types.
There is no instantiation of a \texttt{List<?>}.
It is a placeholder type which can hold any kind of list like
\texttt{List<String>} or \texttt{List<Object>}.
This type can also change at any given time, for example when multiple threads
are using the same field of type \texttt{List<?>}.
A wildcard \texttt{?} must be considered a different type everytime it is accessed.
Therefore calling the method \texttt{concat} with two wildcard lists in the example in listing \ref{lst:concatError} is incorrect.
The \texttt{concat} method does not create a new list,
but adds all elements from the second argument to the list given as the first argument.
This is allowed in Java, because both lists are of the polymorphic type \texttt{List<X>}.
As shown in listing \ref{lst:concatError} this leads to a inconsistent \texttt{List<String>}
if Java would treat \texttt{?} as a regular type and instantiate the type variable \texttt{X}
of the \texttt{concat} function with \texttt{?}.
To enable the use of wildcards in argument types of a method invocation
Java uses a process called \textit{Capture Conversion}.
\begin{lstlisting}[caption=Concat Example,label=lst:concatError]{java}
<X> List<X> concat(List<X> l1, List<X> l2){
return l1.addAll(l2);
}
List<String> ls = new List<String>();
List<?> l1 = ls;
List<?> l2 = new List<Integer>(1);
concat(l1, l2);
\end{lstlisting}
%Existential types enable us to formalize Java's method call behavior and the so called Capture Conversion.
\begin{displaymath}
%TODO:
\begin{array}{l}
\begin{array}{@{}c}
\textit{mtype}(\texttt{concat}) = \generics{\type{X}}\ \exptype{List}{\type{X}} \to \exptype{List}{\type{X}} \to \exptype{List}{\type{X}} \\
\texttt{l1} : \wctype{\rwildcard{A}}{List}{\rwildcard{A}}, \texttt{l2} : \wctype{\rwildcard{B}}{List}{\rwildcard{B}} \\
\exptype{List}{\rwildcard{A}} \nless: [{\color{red}?}/\type{X}]\exptype{List}{\type{X}} \quad \quad
\exptype{List}{\rwildcard{B}} \nless: [{\color{red}?}/\type{X}]\exptype{List}{\type{X}}
\\
\hline
\vspace*{-0.3cm}\\
\texttt{concat}(\expr{l1}, \expr{l2}) : {\color{red}\textbf{Errror}}
\end{array}
\end{array}
\end{displaymath}
%A method call in Java makes use of the fact that a real type is behind a wildcard type
\item \begin{example} \label{intro-example1}
The first one is a valid Java program.
The type \texttt{List<? super String>} is \textit{capture converted} to a fresh type variable $\rwildcard{X}$

View File

@ -2,6 +2,8 @@
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}.
Our calculus is a subset of the calculus defined by \textit{Bierhoff} \cite{WildcardsNeedWitnessProtection}
with the exception that type annotations are optional in our calculus.
Our algorithm is an extension of the \emph{Global Type Inference for Featherweight Generic Java}\cite{TIforFGJ} algorithm.
The input language is designed to showcase type inference involving existential types.