%TODO: % -Explain { % A a; % B b; % } % class Pair extends SuperPair{ % A a; % B b; % X choose(X a, X b){ return b; } % String m(List> a, List> b){ % return choose(choose(a,b).value.a,b.value.b); % } % } % \end{verbatim} \begin{figure}%[tp] \begin{subfigure}[t]{\linewidth} \begin{lstlisting}[style=fgj] class List { List add(A v) { ... } } class Example { m(l, la, lb){ return l .add(la.add(1)) .add(lb.add("str")); } } \end{lstlisting} \caption{Java method with missing return type} \label{fig:nested-list-example-typeless} \end{subfigure} ~ % \begin{subfigure}[t]{\linewidth} % \begin{lstlisting}[style=tfgj] % class List { % List add(A v) { ... } % } % class Example { % m(l, la, lb){ % return let r2 : (*@$\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$@*) = { % let r1 : (*@$\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}}$@*) = l in { % let p1 : (*@$\exptype{List}{\type{Integer}}$@*) = { % let xa = la in xa.add(1) % } in x1.add(p1) % } in { % let p2 = { % let xb = lb in xb.add("str") % } in x2.add(p2) % }; % } % } % \end{lstlisting} % \caption{Featherweight Java Representation} % \label{fig:nested-list-example-let} % \end{subfigure} % ~ \begin{subfigure}[t]{\linewidth} \begin{lstlisting}[style=tfgj] class List { List add(A v) { ... } } class Example { m(List> l, List la, List lb){ return l .add(la.add(1)) .add(lb.add("str")); } } \end{lstlisting} \caption{Java Representation} \label{fig:nested-list-example-typed} \end{subfigure} %\caption{Example code} %\label{fig:intro-example-code} \end{figure} %TODO % The goal is to proof soundness in respect to the type rules introduced by \cite{aModelForJavaWithWildcards} % and \cite{WildcardsNeedWitnessProtection}. \begin{figure}%[tp] \begin{subfigure}[t]{0.49\linewidth} \begin{lstlisting}[style=fgj] genList() { if( ... ) { return new List(); } else { return new List(); } } \end{lstlisting} \caption{Java method with missing return type} \label{fig:intro-example-typeless} \end{subfigure} ~ \begin{subfigure}[t]{0.49\linewidth} \begin{lstlisting}[style=tfgj] List genList() { if( ... ) { return new List(); } else { return new List(); } } \end{lstlisting} \caption{Correct type} \label{fig:intro-example-typed} \end{subfigure} %\caption{Example code} %\label{fig:intro-example-code} \end{figure} % \subsection{Wildcards} % Java subtyping involving generics is invariant. % For example \texttt{List} is not a subtype of \texttt{List}. % %Wildcards introduce variance by allowing \texttt{List} to be a subtype of \texttt{List}. % \texttt{List} is not a valid return type for the method \texttt{genList}. % The type inference algorithm has to find the correct type involving wildcards (\texttt{List}). \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. Generally Java has invariant subtyping for polymorphic types. A \texttt{List} is not a subtype of \texttt{List} for example even though it seems intuitive with \texttt{String} being a subtype of \texttt{Object}. Wildcards can be formalized as existential types \cite{WildFJ}. \texttt{List} and \texttt{List} are both wildcard types 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}}$. 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}. 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}. In Java this is done implicitly in a process called capture conversion. %show input and a correct letFJ representation %TODO: first show local type inference and explain lessdotCC constraints. then show example with global TI \begin{figure}[h] \begin{subfigure}[t]{0.47\textwidth} \centering \begin{lstlisting}[style=tfgj, caption=Valid Java program, label=lst:addExample] List add(List l, A v) ... List l = ...; add(l, "String"); \end{lstlisting} \end{subfigure}\hfill \begin{subfigure}[t]{0.47\textwidth} \centering \begin{lstlisting}[style=letfj, caption=\letfj{} representation, label=lst:addExampleLet] List add(List l, A v) let l2 : (*@$\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}}$@*) = l in add(l2, "String"); \end{lstlisting} \end{subfigure} \end{figure} The Example in listing \ref{lst:addExample} is a valid Java program. Here Java uses local type inference \cite{JavaLocalTI} to determine the type parameters to the \texttt{add} method call. In \letfj{} there is no local type inference and all type parameters for a method call are mandatory (see listing \ref{lst:addExampleLet}). If wildcards are involved the so called capture conversion has to be done manually via let statements. %A let statement \emph{opens} an existential type. In the body of the let statement the \textit{capture type} $\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}}$ becomes $\exptype{List}{\rwildcard{X}}$ and the wildcard $\wildcard{X}{\type{Object}}{\type{String}}$ is free and can be used as a type parameter to \texttt{add(...)}. %This is a valid Java program where the type parameters for the polymorphic method \texttt{add} %are determined by local type inference. 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 extends Object {...} class List2D extends List> {...} void shuffle(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=letfj] let l2d' : (*@$\wctype{\rwildcard{X}}{List}{\exptype{List}{\rwildcard{X}}}$@*) = l2d in shuffle(l2d') \end{lstlisting} \subsection{Global Type Inference} \begin{description} \item[input] \tifj{} program \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})$. \textit{Note:} a type $\type{T}$ can either be a named type, a type placeholder $\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}. \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{TIforFGJ}. The novel capture constraints and wildcard placeholders are needed for method invocations involving wildcards. \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} % Lets have a look at the constraints generated by \fjtype{} for the example in listing \ref{lst:addExample}: \begin{constraintset} \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} \\ \hline \textit{Capture Conversion:}\ \exptype{List}{\rwildcard{X}} \lessdot \exptype{List}{\wtv{a}}, \, \type{String} \lessdot \wtv{a} \\ \hline \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{center} \end{constraintset} % Capture Constraints $(\wctype{\rwildcard{X}}{C}{\rwildcard{X}} \lessdotCC \type{T})$ allow for a capture conversion, which converts a constraint of the form $(\wctype{\rwildcard{X}}{C}{\rwildcard{X}} \lessdotCC \type{T})$ to $(\exptype{C}{\rwildcard{X}} \lessdot \type{T})$ %These constraints are used at places where a capture conversion via let statement can be added. %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}). Therefore we assign the constraint $\wctype{\wildcard{X}{\type{Object}}{\type{String}}}{List}{\rwildcard{X}} \lessdotCC \exptype{List}{\wtv{a}}$ which allows \unify{} to do a capture conversion to $\exptype{List}{\rwildcard{X}} \lessdot \exptype{List}{\wtv{a}}$. \textit{Note:} The constraint $\type{String} \lessdot \rwildcard{X}$ is satisfied because $\rwildcard{X}$ has $\type{String}$ as lower bound. 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}}}$ % No capture conversion for methods in the same class: % Given two methods without type annotations like % \begin{verbatim} % // m :: () -> r % m() = new List() :? new List(); % // id :: (a) -> a % id(a) = a % \end{verbatim} % and a method call \texttt{id(m())} would lead to the constraints: % $\exptype{List}{\type{String}} \lessdot \ntv{r}, % \exptype{List}{\type{Integer}} \lessdot \ntv{r}, % \ntv{r} \lessdotCC \ntv{a}$ % In this example capture conversion is not applicable, % because the \texttt{id} method is not polymorphic. % The type solution provided by \unify{} for this constraint set is: % $\sigma(\ntv{r}) = \wctype{\rwildcard{X}}{List}{\rwildcard{X}}, % \sigma(\ntv{a}) = \wctype{\rwildcard{X}}{List}{\rwildcard{X}}$ % \begin{verbatim} % List m() = new List() :? new List(); % List id(List a) = a % \end{verbatim} % The following example has the \texttt{id} method already typed and the method \texttt{m} % extended by a recursive call \texttt{id(m())}: % \begin{verbatim} % List id(List a) = a % m() = new List() :? new List() :? id(m()); % \end{verbatim} % Now the constraints make use of a $\lessdotCC$ constraint: % $\exptype{List}{\type{String}} \lessdot \ntv{r}, % \exptype{List}{\type{Integer}} \lessdot \ntv{r}, % \ntv{r} \lessdotCC \exptype{List}{\wtv{a}}$ % After substituting $\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$ for $\ntv{r}$ like in the example before % we get the constraint $\wctype{\rwildcard{X}}{List}{\rwildcard{X}} \lessdotCC \exptype{List}{\wtv{a}}$. % Due to the $\lessdotCC$ \unify{} is allowed to perform a capture conversion yielding % $\exptype{List}{\rwildcard{X}} \lessdot \exptype{List}{\wtv{a}}$. % \textit{Note:} The wildcard placeholder $\wtv{a}$ is allowed to hold free variables whereas a normal placeholder like $\ntv{r}$ % is never assigned a type containing free variables. % Therefore \unify{} sets $\wtv{a} \doteq \rwildcard{X}$, completing the constraint set and resulting in the type solution: % \begin{verbatim} % List m() = new List() :? new List() :? id(m()); % \end{verbatim} \subsection{Challenges}\label{challenges} %TODO: Wildcard subtyping is infinite see \cite{TamingWildcards} The introduction of wildcards adds additional challenges. % we cannot replace every type variable with a wildcard Type variables can also be used as type parameters, for example $\exptype{List}{String} \lessdot \exptype{List}{\tv{a}}$. A problem arises when replacing type variables with wildcards. % Wildcards are not reflexive. % ( on the equals property ), every wildcard has to be capture converted when leaving its scope % do not substitute free type variables Lets have a look at two examples: \begin{itemize} \item \begin{example} \label{intro-example1} The first one is a valid Java program. The type \texttt{List} is \textit{capture converted} to a fresh type variable $\rwildcard{X}$ which is used as the generic method parameter \texttt{A}. Java uses capture conversion to replace the generic \texttt{A} by a capture converted version of the \texttt{? super String} wildcard. Knowing that the type \texttt{String} is a subtype of any type the wildcard \texttt{? super String} can inherit it is safe to pass \texttt{"String"} for the first parameter of the function. \begin{verbatim} List add(List l, A v) {} List list = ...; add("String", list); \end{verbatim} \end{example} \item \begin{example}\label{intro-example2} This example displays an incorrect Java program. The method call to \texttt{concat} with two wildcard lists is unsound. Each list could be of a different kind and therefore the \texttt{concat} cannot succeed. \begin{verbatim} List concat(List l1, List l2) { ... } List list = ... ; concat(list, list); \end{verbatim} % $\wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}} \lessdot \exptype{List}{\wtv{a}}, \\ % \wctype{\wildcard{X}{\type{Object}}{\bot}}{List}{\rwildcard{X}} \lessdot \exptype{List}{\wtv{a}}$ \end{example} % \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() :? new List() % 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{No principal method type:} We tried to skip capture conversion and the capture constraints entirely. But \letfj{}'s type system does not imply a principal typing for methods \cite{principalTypes}. The problem is that a principal type of a method should have the most general parameter types and the most specific return type. \begin{lstlisting}[caption=Return type depends on argument types,label=principalTypeExample] class SpecialPair2 extends Pair{} Pair id(Pair in){ return ...; } void receive(Pair in){} Pair l; SpecialPair lSpecial; id(l); // this has to work receive(id(lSpecial)); // and this too \end{lstlisting} By means of subtyping we are able to create types like $\wctype{\rwildcard{X}, \wildcard{Y}{\rwildcard{X}}{\bot}}{Pair}{\rwildcard{X}, \rwildcard{Y}}$ as a direct supertype of \texttt{SpecialPair}, which is now compatible with the \texttt{receive} method. The call \texttt{receive(id(lSpecial))} is correct whereas the return type of the \texttt{id} method does not imply so. If we look at this in the context of global type inference and assume that there are no type annotations for \texttt{l} and \texttt{lSpecial}. We can neither apply capture conversion during the constraint generation step, because the parameter types are not known yet and we also can't assume a most generic type for the parameter types, because the the needed return type is not known either. Take the example in figure \ref{fig:principalTI}. As soon as the type of $\tv{lSpecial}$ is resolved \unify{} can determine the type of $\tv{id}$ and then solve the constraints $\tv{id} \lessdotCC \exptype{Pair}{\wtv{e}, \wtv{f}}, \wtv{f} \lessdot \wtv{e}$. %TODO: explain how type variables are named after their respective variables and methods Capture Conversion cannot be applied before the argument type ($\tv{lSpecial}$ in this case) is known. Trying to give $\tv{lSpecial}$ a most general type like \texttt{Pair} won't work either (see listing \ref{principalTypeExample}). \begin{figure} \begin{minipage}{0.40\textwidth} \begin{lstlisting}[style=tfgj] // l and lSpecial are untyped id(l); receive(id(lSpecial)); \end{lstlisting} \end{minipage}% \hfill \begin{minipage}{0.59\textwidth} \begin{constraintset} $ \tv{l} \lessdotCC \exptype{Pair}{\wtv{a}, \wtv{b}}, \\ \tv{lSpecial} \lessdotCC \exptype{Pair}{\wtv{c}, \wtv{d}}, \exptype{Pair}{\wtv{c}, \wtv{d}} \lessdot \tv{id}, \\ \tv{id} \lessdotCC \exptype{Pair}{\wtv{e}, \wtv{f}}, \wtv{f} \lessdot \wtv{e} $ \end{constraintset} \end{minipage} \caption{Principal Type problem}\label{fig:principalTI} \end{figure} % TODO: make Unify to resolve C <. a as a =. X.C \end{itemize} %TODO: Move this part. or move the third challenge some underneath. The \unify{} algorithm only sees the constraints with no information about the program they originated from. The main challenge was to find an algorithm which computes $\sigma(\wtv{a}) = \rwildcard{X}$ for example \ref{intro-example1} but not for example \ref{intro-example2}. \subsection{Capture Conversion} The input to our type inference algorithm does not contain let statements. Those are added after computing a type solution. Let statements act as capture conversion and only have to be applied in method calls involving wildcard types. \begin{figure} \begin{minipage}{0.45\textwidth} \begin{lstlisting}[style=fgj] List clone(List l); example(p){ return clone(p); } \end{lstlisting} \end{minipage}% \hfill \begin{minipage}{0.5\textwidth} \begin{lstlisting}[style=tfgj] (*@$\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$@*) example((*@$\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$@*) p){ return let x : (*@$\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$@*) = p in clone(x) : (*@$\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$@*); } \end{lstlisting} \end{minipage} \caption{Type inference adding capture conversion}\label{fig:addingLetExample} \end{figure} Figure \ref{fig:addingLetExample} shows a let statement getting added to the typed output. The method \texttt{clone} cannot be called with the type $\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$. After a capture conversion \texttt{x} has the type $\exptype{List}{\rwildcard{X}}$ with $\rwildcard{X}$ being a free variable. Afterwards we have to find a supertype of $\exptype{List}{\rwildcard{X}}$, which does not contain free variables ($\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$ in this case). During the constraint generation step most types are not known yet and are represented by a type placeholder. During a methodcall like the one in the \texttt{example} method in figure \ref{fig:ccExample} the type of the parameter \texttt{p} is not known yet. The type \texttt{List} would be one possibility as a parameter type for \texttt{p}. To make wildcards work for our type inference algorithm \unify{} has to apply capture conversions if necessary. The type placeholder $\tv{r}$ is the return type of the \texttt{example} method. One possible type solution is $\tv{p} \doteq \tv{r} \doteq \wctype{\rwildcard{X}}{List}{\rwildcard{X}}$, which leads to: \begin{verbatim} List example(List p){ return clone(p); } \end{verbatim} But by substituting $\tv{p} \doteq \wctype{\rwildcard{X}}{List}{\rwildcard{X}}$ in the constraint $\tv{p} \lessdotCC \exptype{List}{\wtv{x}}$ leads to $\wctype{\rwildcard{X}}{List}{\rwildcard{X}} \lessdotCC \exptype{List}{\wtv{x}}$. To make this typing possible we have to introduce a capture conversion via a let statement: $\texttt{return}\ (\texttt{let}\ \texttt{x} : \wctype{\rwildcard{X}}{List}{\rwildcard{X}} = \texttt{p}\ \texttt{in} \ \texttt{clone}\generics{\rwildcard{X}}(x) : \wctype{\rwildcard{X}}{List}{\rwildcard{X}})$ Inside the let statement the variable \texttt{x} has the type $\exptype{List}{\rwildcard{X}}$ This spawns additional problems. \begin{figure} \begin{minipage}{0.45\textwidth} \begin{verbatim} List clone(List l){...} example(p){ return clone(p); } \end{verbatim} \end{minipage}% \hfill \begin{minipage}{0.35\textwidth} \begin{constraintset} \textbf{Constraints:}\\ $ \tv{p} \lessdotCC \exptype{List}{\wtv{x}}, \\ \tv{p} \lessdot \tv{r}, \\ \tv{p} \lessdot \type{Object}, \tv{r} \lessdot \type{Object} $ \end{constraintset} \end{minipage} \caption{Type inference example}\label{fig:ccExample} \end{figure} In addition with free variables this leads to unwanted behaviour. Take the constraint $\wctype{\rwildcard{X}}{List}{\rwildcard{X}} \lessdot \exptype{List}{\wtv{a}}$ for example. After a capture conversion from $\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$ to $\exptype{List}{\rwildcard{Y}}$ and a substitution $\wtv{a} \doteq \rwildcard{Y}$ we get $\exptype{List}{\rwildcard{Y}} \lessdot \exptype{List}{\rwildcard{Y}}$. Which is correct if we apply capture conversion to the left side: $\exptype{List}{\rwildcard{X}} <: \exptype{List}{\rwildcard{X}}$ If the input constraints did not intend for this constraint to undergo a capture conversion then \unify{} would produce an invalid type solution due to: $\wctype{\rwildcard{X}}{List}{\rwildcard{X}} \nless: \exptype{List}{\rwildcard{X}}$ The reason for this is the \texttt{S-Exists} rule's premise $\text{dom}(\Delta') \cap \text{fv}(\exptype{List}{\rwildcard{X}}) = \emptyset$. Additionally free variables are not allowed to leave the scope of a capture conversion introduced by a let statement. %TODO we combat both of this with wildcard type placeholders (? flag) Type placeholders which are not flagged as possible free variables ($\wtv{a}$) can never hold a free variable or a type containing free variables. Constraint generation places these standard place holders at method return types and parameter types. \begin{lstlisting}[style=fgj] List clone(List l); (*@$\red{\tv{r}}$@*) example((*@$\red{\tv{p}}$@*) p){ return clone(p); } \end{lstlisting} This prevents type solutions that contain free variables in parameter and return types. When calling a method which already has a type annotation we have to consider adding a capture conversion in form of a let statement. The constraint $\tv{p} \lessdot \exptype{List}{\wtv{x}}$ signals the \unify{} algorithm that here a capture conversion is possible. $\sigma(\tv{p}) = \wctype{\rwildcard{X}}{List}{\rwildcard{X}}, \sigma(\tv{r}) = \wctype{\rwildcard{X}}{List}{\rwildcard{X}}, $ is a possible solution. But only when adding a capture conversion: \begin{lstlisting}[style=fgj] List clone(List l); (*@$\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$@*) example((*@$\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$@*) p){ return let x : (*@$\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$@*) = p in clone(x) : (*@$\wctype{\rwildcard{X}}{List}{\rwildcard{X}}$@*); } \end{lstlisting} Capture constraints cannot be stored in a set. $\wtv{a} \lessdotCC \wtv{b}$ is not the same as $\wtv{a} \lessdotCC \wtv{b}$. Both constraints will end up the same after a substitution for both placeholders $\tv{a}$ and $\tv{b}$. But afterwards a capture conversion is applied, which can generate different types on the left sides. \begin{itemize} \item $\text{CC}(\wctype{\rwildcard{X}}{List}{\rwildcard{X}}) \implies \exptype{List}{\rwildcard{Y}}$ \item $\text{CC}(\wctype{\rwildcard{X}}{List}{\rwildcard{X}}) \implies \exptype{List}{\rwildcard{Z}}$ \end{itemize}