Add Wildcard introduction
This commit is contained in:
parent
5cd90a9593
commit
b432c5b091
106
introduction.tex
106
introduction.tex
@ -4,6 +4,17 @@
|
|||||||
% - Kapitel 1.2 + 1.3 ist noch zu komplex
|
% - Kapitel 1.2 + 1.3 ist noch zu komplex
|
||||||
% - Constraints und Unifikation erklären, bevor Unifikation erwähnt wird
|
% - Constraints und Unifikation erklären, bevor Unifikation erwähnt wird
|
||||||
|
|
||||||
|
%Inhalt:
|
||||||
|
% Global type inference example (the sameList example)
|
||||||
|
% Wildcards are needed because Java has side effects
|
||||||
|
% Capture Conversion
|
||||||
|
% Explain difference between local and global type inference
|
||||||
|
|
||||||
|
someList(){}
|
||||||
|
concat(l1, l2){
|
||||||
|
return l1.add(l2)
|
||||||
|
}
|
||||||
|
|
||||||
\section{Motivation}
|
\section{Motivation}
|
||||||
Java already uses type inference when it comes to method invocations, local variables or lambda expressions.
|
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 crucial part for all of this use cases is the surrounding context.
|
||||||
@ -18,7 +29,7 @@ List<String> ls = emptyList();
|
|||||||
Local type inference is based on matching and not unification \cite{javaTIisBroken}.
|
Local type inference is based on matching and not unification \cite{javaTIisBroken}.
|
||||||
When calling the \texttt{emptyList} method without context its return value will be set to a \texttt{List<Object>}.
|
When calling the \texttt{emptyList} method without context its return value will be set to a \texttt{List<Object>}.
|
||||||
The following Java code snippet is incorrect, because \texttt{emptyList()} returns
|
The following Java code snippet is incorrect, because \texttt{emptyList()} returns
|
||||||
a \texttt{List<Object>} instead of the required \texttt{List<List<String>>}.
|
a \texttt{List<Object>} instead of the required $\exptype{List}{\exptype{List}{String}}$.
|
||||||
\begin{verbatim}
|
\begin{verbatim}
|
||||||
emptyList().add(new List<String>())
|
emptyList().add(new List<String>())
|
||||||
.get(0)
|
.get(0)
|
||||||
@ -281,22 +292,101 @@ List<?> genList() {
|
|||||||
% The type inference algorithm has to find the correct type involving wildcards (\texttt{List<?>}).
|
% The type inference algorithm has to find the correct type involving wildcards (\texttt{List<?>}).
|
||||||
|
|
||||||
\subsection{Java Wildcards}
|
\subsection{Java Wildcards}
|
||||||
Wildcards are expressed by a \texttt{?} in Java and can be used as type parameters.
|
|
||||||
Wildcards add variance to Java type parameters.
|
Java has invariant subtyping for polymorphic types
|
||||||
Generally Java has invariant subtyping for polymorphic types.
|
and incooperates use-site variance via so called wildcard types.
|
||||||
A \texttt{List<String>} is not a subtype of \texttt{List<Object>} for example
|
A \texttt{List<String>} is not a subtype of \texttt{List<Object>} for example
|
||||||
even though it seems intuitive with \texttt{String} being a subtype of \texttt{Object}.
|
even though it seems intuitive with \texttt{String} being a subtype of \texttt{Object}.
|
||||||
|
Class instances in Java are mutable and passed by reference.
|
||||||
|
Subtyping must be invariant otherwise the integrity of data classes like lists could be
|
||||||
|
corrupted like shown in listing \ref{lst:invarianceExample},
|
||||||
|
where an \texttt{Integer} is added to a list of \texttt{String}.
|
||||||
|
|
||||||
|
\begin{minipage}{0.4\textwidth}
|
||||||
|
\begin{lstlisting}[caption=Java Invariance Example,label=lst:invarianceExample]{java}
|
||||||
|
List<String> ls = ...;
|
||||||
|
List<Object> lo = ...;
|
||||||
|
lo = ls; // typing error!
|
||||||
|
lo.add(new Integer(1));
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{minipage}
|
||||||
|
\hfill
|
||||||
|
\begin{minipage}{0.5\textwidth}
|
||||||
|
\begin{lstlisting}[caption=Use-Site Variance Example]{java}
|
||||||
|
List<String> ls = ...;
|
||||||
|
List<? extends Object> lo = ...;
|
||||||
|
lo = ls; // correct
|
||||||
|
lo.add(new Integer(1)); // error!
|
||||||
|
\end{lstlisting}
|
||||||
|
\end{minipage}
|
||||||
|
|
||||||
|
|
||||||
Wildcards can be formalized as existential types \cite{WildFJ}.
|
Wildcards can be formalized as existential types \cite{WildFJ}.
|
||||||
\texttt{List<? extends Object>} and \texttt{List<? super String>} are both wildcard types
|
A \texttt{List<? extends Object>} is translated to $\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$
|
||||||
denoted in our syntax by $\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$ and
|
and \texttt{List<? super String>} is expressed as $\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}}$.
|
||||||
$\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}}$.
|
|
||||||
|
|
||||||
|
%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
|
||||||
|
|
||||||
|
|
||||||
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}.
|
||||||
|
|
||||||
Those properties are needed to formalize capture conversion.
|
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}.
|
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.
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user