Yet more tidying of the HATRA paper

This commit is contained in:
ajeffrey@roblox.com 2021-07-16 18:28:05 -05:00
parent f31006319f
commit 8329fdff26
2 changed files with 46 additions and 39 deletions

Binary file not shown.

View file

@ -6,13 +6,14 @@
\acmConference[HATRA '21]{Human Aspects of Types and Reasoning Assistants}{October 2021}{Chicago, IL} \acmConference[HATRA '21]{Human Aspects of Types and Reasoning Assistants}{October 2021}{Chicago, IL}
\acmBooktitle{HATRA '21: Human Aspects of Types and Reasoning Assistants} \acmBooktitle{HATRA '21: Human Aspects of Types and Reasoning Assistants}
\newcommand{\squnder}[1]{\underline{#1}} \newcommand{\squnder}[1]{\color{red}\underline{{\color{black}#1}}\color{black}}
\newcommand{\infer}[2]{\frac{\textstyle#1}{\textstyle#2}} \newcommand{\infer}[2]{\frac{\textstyle#1}{\textstyle#2}}
\newcommand{\erase}{\mathrm{erase}} \newcommand{\erase}{\mathrm{erase}}
\newcommand{\evCtx}{\mathcal{E}} \newcommand{\evCtx}{\mathcal{E}}
\newcommand{\NIL}{\mathsf{nil}} \newcommand{\NIL}{\mathsf{nil}}
\newcommand{\TRUE}{\mathsf{true}} \newcommand{\TRUE}{\mathsf{true}}
\newcommand{\FALSE}{\mathsf{false}} \newcommand{\FALSE}{\mathsf{false}}
\newcommand{\NUMBER}{\mathsf{number}}
\newcommand{\ERROR}{\mathsf{error}} \newcommand{\ERROR}{\mathsf{error}}
\newcommand{\IF}{\mathsf{if}\,} \newcommand{\IF}{\mathsf{if}\,}
\newcommand{\THEN}{\,\mathsf{then}\,} \newcommand{\THEN}{\,\mathsf{then}\,}
@ -153,7 +154,7 @@ even to creators who are not explicitly providing types.
\section{Types} \section{Types}
\subsection{Infallible types} \subsection{Infallible types}
Goal: \emph{support type-driven tools in all programs}. Goal: \emph{support type-driven tools for all programs}.
Programs spend much of their time under development in an incomplete state, even if the final arifact Programs spend much of their time under development in an incomplete state, even if the final arifact
is well-typed. Type-driven tools should support this, by providing type information for all programs. is well-typed. Type-driven tools should support this, by providing type information for all programs.
@ -161,10 +162,10 @@ An analogy is infallible parsers, which perform error recovery and provide an AS
Program analysis can still flag type errors, for example with red Program analysis can still flag type errors, for example with red
squiggly underlining. Formalizing this, rather than a judgement squiggly underlining. Formalizing this, rather than a judgement
$\Gamma\vdash M:T$, for an input terms $M$, there is a judgement $\Gamma\vdash M:T$, for an input term $M$, there is a judgement
$\Gamma \vdash M \Rightarrow M' : T$ where $M'$ is an output term $\Gamma \vdash M \Rightarrow N : T$ where $N$ is an output term
where some subterms are flagged $\squnder{M}$. Write $\erase(M)$ where some subterms are \emph{flagged} $\squnder{N}$. Write $\erase(N)$
for the result of erasing flagged type errors: $\erase(\squnder{M}) = \erase(M)$. for the result of erasing flaggings: $\erase(\squnder{N}) = \erase(N)$.
%% For example the usual %% For example the usual
%% type rules for field access becomes: %% type rules for field access becomes:
@ -194,9 +195,9 @@ for the result of erasing flagged type errors: $\erase(\squnder{M}) = \erase(M)$
The goal of infallible types is that every term can be typed: The goal of infallible types is that every term can be typed:
\begin{itemize} \begin{itemize}
\item \emph{Typability}: for every $M$ and $\Gamma$, \item \emph{Typability}: for every $M$ and $\Gamma$,
there are $M'$ and $T$ such that $\Gamma \vdash M \Rightarrow M' : T$. there are $N$ and $T$ such that $\Gamma \vdash M \Rightarrow N : T$.
\item \emph{Erasure}: if $\Gamma \vdash M \Rightarrow M' : T$ \item \emph{Erasure}: if $\Gamma \vdash M \Rightarrow N : T$
then $\erase(M) = \erase(M')$ then $\erase(M) = \erase(N)$
\end{itemize} \end{itemize}
Some issues raised by infallible types: Some issues raised by infallible types:
\begin{itemize} \begin{itemize}
@ -209,7 +210,9 @@ Some issues raised by infallible types:
\end{itemize} \end{itemize}
Related work: lots on type error reporting~\cite{???}, and on Related work: lots on type error reporting~\cite{???}, and on
heuristics for program repair~\cite{???}, but not type repair, or on heuristics for program repair~\cite{???}, but not type repair, or on
the semantics of programs with type errors. the semantics of programs with type errors. Many compilers perform
error recovery during typechecking, but do not provide a semantiocs
for programs with type errors.
\subsection{Strict types} \subsection{Strict types}
@ -225,19 +228,26 @@ progress. This requires:
\item \emph{Operational semantics}: a reduction judgement $M \rightarrow N$ on terms. \item \emph{Operational semantics}: a reduction judgement $M \rightarrow N$ on terms.
\item \emph{Values}: a subset of terms representing a successfully completed evaluation. \item \emph{Values}: a subset of terms representing a successfully completed evaluation.
\end{itemize} \end{itemize}
We then represent error states as stuck states (terms that are not Error states at runtime are represented as stuck states (terms that are not
values but cannot reduce), and showing that no well-typed program is values but cannot reduce), and showing that no well-typed program is
stuck. This is not true if typing is infallible, but can fairly stuck. This is not true if typing is infallible, but can fairly
straightforwardly be adapted: straightforwardly be adapted, by extending the operational semantics to flagged terms:
\begin{itemize} \begin{itemize}
\item \emph{Progress}: if ${} \vdash M \Rightarrow M'$, then either $M \rightarrow N$ or $M$ is a value or $M'$ is flagged. \item If $M \rightarrow M'$ then $\squnder{M} \rightarrow \squnder{M'}$.
\item \emph{Preservation}: if ${} \vdash M \Rightarrow M'$ and $M \rightarrow N$ and ${} \vdash N \Rightarrow N'$ and $N'$ is flagged, then $M'$ is flagged. \item If $V$ is a value, then $\squnder{V} \rightarrow V$.
\end{itemize}
and defining:
\begin{itemize}
\item \emph{Progress}: if ${} \vdash M \Rightarrow N$, then either $N \rightarrow N'$ or $N$ is a value or $N$ has a flagged subterm.
\item \emph{Preservation}: if $N \rightarrow N'$ and $N'$ has a flagged subterm, then $N$ has a flagged subterm.
\end{itemize} \end{itemize}
Some issues raised by infallible types: Some issues raised by infallible types:
\begin{itemize} \begin{itemize}
\item How should the judgements and their metatheory be set up? \item How should the judgements and their metatheory be set up?
\item How should generic functions be handled? \item How should type inference and generic functions be handled?
\item What does type inference or bidirectional typechecking look like in this setting? \item Is the operational semantics of flagged values
($\squnder{V} \rightarrow V$) the right one?
\item Will higher-order code require wrappers on functions?
\end{itemize} \end{itemize}
Related work: blame analysis~\cite{???}. Related work: blame analysis~\cite{???}.
@ -246,8 +256,9 @@ Related work: blame analysis~\cite{???}.
Goal: \emph{no false positives.} Goal: \emph{no false positives.}
For developers who are not interested in defect detection, type-driven For developers who are not interested in defect detection, type-driven
tools such as autocomplete can still be useful, and type-directed tools and techniques such as autocomplete, API documentation
development can still be useful. For such developers, Luau provides a and support for refactoring can still be useful.
For such developers, Luau provides a
\emph{nonstict mode}, which we hope will eventually be useful for all \emph{nonstict mode}, which we hope will eventually be useful for all
developers. This does \emph{not} aim for soundness, but instead has developers. This does \emph{not} aim for soundness, but instead has
the goal of ``no false positives``, in the sense that any flagged code the goal of ``no false positives``, in the sense that any flagged code
@ -255,21 +266,18 @@ is guaranteed to produce a runtime error when executed.
On the face of it, this is undecidable, since a program such as On the face of it, this is undecidable, since a program such as
$(\IF f() \THEN \ERROR \END)$ will produce a runtime error when $f()$ is $(\IF f() \THEN \ERROR \END)$ will produce a runtime error when $f()$ is
$\TRUE$, but we can aim for a weaker property, thjat all flagged code $\TRUE$, but we can aim for a weaker property, that all flagged code
is either dead code or will produce an error. Either of these is a is either dead code or will produce an error. Either of these is a
defect, so deserves flagging, even if the tool does not know defect, so deserves flagging, even if the tool does not know
which. For example, using this definition which reason applies. For example, using this definition
$(\IF f() \THEN \squnder{\ERROR} \END)$ is not a false positive, but $(\IF f() \THEN \squnder{\ERROR} \END)$ is not a false positive.
$(\squnder{\IF f() \THEN \ERROR \END})$ might be.
We can formalize this by defining an \emph{evaluation context} We can formalize this by defining an \emph{evaluation context}
$\evCtx[\bullet]$, defining a \emph{redex} of $M$ to be a subterm $N$ $\evCtx[\bullet]$, and saying $M$ is \emph{incorrectly flagged}
such that $M = \evCtx[N]$, and defining $M{\Uparrow}$ when there is no if it is of the form $\evCtx[\squnder{V}]$. We can then define:
value $V$ such that $M \rightarrow^* V$. We can then define:
\begin{itemize} \begin{itemize}
\item \emph{Snappy name}: if ${} \vdash M \Rightarrow M'$ and $M'$ has a flagged redex \item \emph{Correct flagging}: if ${} \vdash M \Rightarrow M'$ and
then $M{\Uparrow}$. $M' \rightarrow^* N'$ then $N'$ is correctly flagged.
\end{itemize} \end{itemize}
Some issues raised by nonstrict types: Some issues raised by nonstrict types:
\begin{itemize} \begin{itemize}
@ -278,21 +286,20 @@ Some issues raised by nonstrict types:
flagging will often move from function definitions to call sites. flagging will often move from function definitions to call sites.
\item This definition will not allow an unchecked use of an optional value \item This definition will not allow an unchecked use of an optional value
to be flagged, for example if we define $\FUNCTION g()\,\IF f() \THEN \RETURN 5 \ELSE \RETURN \NIL \END$ to be flagged, for example if $f() : \NUMBER?$ (meaning $f$ may optionally return a number)
then a strict type system can flag $1 + g()$ but a nonstrict one cannot. then a strict type system can flag $1 + f()$ but a nonstrict one cannot.
\item Property update of tables in languages like Luau always succeeds \item Property update of tables in languages like Luau always succeeds
(the property is inserted if it did not exist), which interacts (the property is inserted if it did not exist), and so functions which
badly with compositional analysis. For example, if module $A$ update properties cannot be flagged.
exports a table $t=\{p=5\}$, module $B$ assumes $t.p$ is a number,
and module $C$ sets $t.p=\FALSE$, then we cannot flag $C$ since the \item Does nonstrict typing require whole program analysis,
assignment will succeed, and we cannot flag $A$ or $B$ without some to find all the possible types a property might be updated with?
whole-program analysis.
\item The natural formulation of function types in a nonstrict setting \item The natural formulation of function types in a nonstrict setting
is that of~\cite{???}: if $f: T \rightarrow U$ and $f(v) \rightarrow^* w$ is that of~\cite{???}: if $f: T \rightarrow U$ and $f(V) \rightarrow^* W$
then $v:T$ and $w:U$. This formulation is \emph{covariant} in $T$, then $V:T$ and $W:U$. This formulation is \emph{covariant} in $T$,
not \emph{contavariant}. not \emph{contavariant}; what impact does this have?
\end{itemize} \end{itemize}
Related work: success types~\cite{???} and incorrectness logic~\cite{???}. Related work: success types~\cite{???} and incorrectness logic~\cite{???}.