mirror of
https://github.com/dhil/phd-dissertation
synced 2026-03-13 11:08:25 +00:00
Tidy up HO translation.
This commit is contained in:
185
thesis.tex
185
thesis.tex
@@ -860,8 +860,9 @@ given term.
|
|||||||
The function computes the set of free variables bottom-up. Most cases
|
The function computes the set of free variables bottom-up. Most cases
|
||||||
are homomorphic on the syntax constructors. The interesting cases are
|
are homomorphic on the syntax constructors. The interesting cases are
|
||||||
those constructs which feature term binders: lambda abstraction, let
|
those constructs which feature term binders: lambda abstraction, let
|
||||||
bindings, pair destructing, and case splitting. In each of those cases
|
bindings, pair deconstructing, and case splitting. In each of those
|
||||||
we subtract the relevant binder(s) from the set of free variables.
|
cases we subtract the relevant binder(s) from the set of free
|
||||||
|
variables.
|
||||||
|
|
||||||
\subsection{Typing rules}
|
\subsection{Typing rules}
|
||||||
\label{sec:base-language-type-rules}
|
\label{sec:base-language-type-rules}
|
||||||
@@ -1007,7 +1008,7 @@ application $V\,A$ is well-typed whenever the abstractor term $V$ has
|
|||||||
the polymorphic type $\forall \alpha^K.C$ and the type $A$ has kind
|
the polymorphic type $\forall \alpha^K.C$ and the type $A$ has kind
|
||||||
$K$. This rule makes use of type substitution.
|
$K$. This rule makes use of type substitution.
|
||||||
%
|
%
|
||||||
The \tylab{Split} rule handles typing of record destructing. When
|
The \tylab{Split} rule handles typing of record deconstructing. When
|
||||||
splitting a record term $V$ on some label $\ell$ binding it to $x$ and
|
splitting a record term $V$ on some label $\ell$ binding it to $x$ and
|
||||||
the remainder to $y$. The label we wish to split on must be present
|
the remainder to $y$. The label we wish to split on must be present
|
||||||
with some type $A$, hence we require that
|
with some type $A$, hence we require that
|
||||||
@@ -1566,9 +1567,9 @@ effect handlers which are an alternative to deep effect handlers.
|
|||||||
%
|
%
|
||||||
Programming with effect handlers is a dichotomy of \emph{performing}
|
Programming with effect handlers is a dichotomy of \emph{performing}
|
||||||
and \emph{handling} of effectful operations -- or alternatively a
|
and \emph{handling} of effectful operations -- or alternatively a
|
||||||
dichotomy of \emph{constructing} and \emph{destructing}. An operation
|
dichotomy of \emph{constructing} and \emph{deconstructing}. An operation
|
||||||
is a constructor of an effect without a predefined semantics. A
|
is a constructor of an effect without a predefined semantics. A
|
||||||
handler destructs effects by pattern-matching on their operations. By
|
handler deconstructs effects by pattern-matching on their operations. By
|
||||||
matching on a particular operation, a handler instantiates the said
|
matching on a particular operation, a handler instantiates the said
|
||||||
operation with a particular semantics of its own choosing. The key
|
operation with a particular semantics of its own choosing. The key
|
||||||
ingredient to make this work in practice is \emph{delimited
|
ingredient to make this work in practice is \emph{delimited
|
||||||
@@ -2534,28 +2535,12 @@ operation clauses extract and convert the current resumption stack
|
|||||||
into a function using the $\Res$, and $\hforward$ augments the current
|
into a function using the $\Res$, and $\hforward$ augments the current
|
||||||
resumption stack with the current continuation pair.
|
resumption stack with the current continuation pair.
|
||||||
%
|
%
|
||||||
% Since we have only changed the representation of resumptions, the
|
|
||||||
% translation of top-level programs remains the same.
|
|
||||||
|
|
||||||
\subsection{Higher-order translation for deep effect handlers}
|
\subsection{Higher-order translation for deep effect handlers}
|
||||||
\label{sec:higher-order-uncurried-deep-handlers-cps}
|
\label{sec:higher-order-uncurried-deep-handlers-cps}
|
||||||
%
|
%
|
||||||
\begin{figure}
|
\begin{figure}
|
||||||
%
|
%
|
||||||
% \textbf{Static patterns and static lists}
|
|
||||||
% %
|
|
||||||
% \begin{syntax}
|
|
||||||
% \slab{Static patterns} &\sP& ::= & \sk \scons \sP \mid \sks \\
|
|
||||||
% \slab{Static lists} &\VS& ::= & V \scons \VS \mid \reflect V \\
|
|
||||||
% \end{syntax}
|
|
||||||
% %
|
|
||||||
% \textbf{Reification}
|
|
||||||
% %
|
|
||||||
% \begin{equations}
|
|
||||||
% \reify (V \scons \VS) &\defas& V \dcons \reify \VS \\
|
|
||||||
% \reify \reflect V &\defas& V \\
|
|
||||||
% \end{equations}
|
|
||||||
%
|
|
||||||
\textbf{Values}
|
\textbf{Values}
|
||||||
%
|
%
|
||||||
\begin{displaymath}
|
\begin{displaymath}
|
||||||
@@ -2594,19 +2579,6 @@ resumption stack with the current continuation pair.
|
|||||||
\cps{-} &:& \HandlerCat \to \UCompCat\\
|
\cps{-} &:& \HandlerCat \to \UCompCat\\
|
||||||
\cps{\{\Return \; x \mapsto N\}} &\defas& \dlam x\, ks.\Let\; (h \dcons ks') = ks \;\In\; \cps{N} \sapp \reflect ks'
|
\cps{\{\Return \; x \mapsto N\}} &\defas& \dlam x\, ks.\Let\; (h \dcons ks') = ks \;\In\; \cps{N} \sapp \reflect ks'
|
||||||
\\
|
\\
|
||||||
% \cps{\{(\ell \; p \; r \mapsto N_\ell)_{\ell \in \mathcal{L}}\}}
|
|
||||||
% &\defas&
|
|
||||||
% \bl
|
|
||||||
% \dlam z \, ks.\Case \;z\; \{
|
|
||||||
% \bl
|
|
||||||
% (\ell~\Record{p, s} \mapsto \dLet\;r=\Fun\,s \;\dIn\; \cps{N_{\ell}} \sapp \reflect ks)_{\ell \in \mathcal{L}};\,
|
|
||||||
% y \mapsto \hforward \} \\
|
|
||||||
% \el \\
|
|
||||||
% \el \\
|
|
||||||
% \hforward &\defas& \bl
|
|
||||||
% \dLet\; (k' \dcons h' \dcons ks') = ks \;\dIn\; \\
|
|
||||||
% \Vmap\,(\dlam\Record{p, s}\,(k \dcons ks).k\,\Record{p, h' \dcons k' \dcons s}\,ks)\,y\,(h' \dcons ks') \\
|
|
||||||
% \el\\
|
|
||||||
\cps{\{(\ell \; p \; r \mapsto N_\ell)_{\ell \in \mathcal{L}}\}}
|
\cps{\{(\ell \; p \; r \mapsto N_\ell)_{\ell \in \mathcal{L}}\}}
|
||||||
&\defas& \bl
|
&\defas& \bl
|
||||||
\dlam \Record{z,\Record{p,rs}}\,ks.\Case \;z\; \{
|
\dlam \Record{z,\Record{p,rs}}\,ks.\Case \;z\; \{
|
||||||
@@ -2666,15 +2638,6 @@ alternating lists of pure continuation functions and effect
|
|||||||
continuation functions. To ease notation we are going make use of
|
continuation functions. To ease notation we are going make use of
|
||||||
pattern matching notation. The static meta language is generated by
|
pattern matching notation. The static meta language is generated by
|
||||||
the following productions.
|
the following productions.
|
||||||
% Static constructs are marked in
|
|
||||||
% {\color{blue}$\overline{\text{static blue}}$}, and their redexes are
|
|
||||||
% reduced as part of the translation (at compile time). We make use of
|
|
||||||
% static lambda abstractions, pairs, and lists. Reflection of dynamic
|
|
||||||
% language values into the static language is written as $\reflect V$.
|
|
||||||
% %
|
|
||||||
% We use $\shk$ for variables representing statically known
|
|
||||||
% continuations (frame stacks), $\shf$ for variables representing pure
|
|
||||||
% frame stacks, and $\chi$ for variables representing handlers.
|
|
||||||
%
|
%
|
||||||
\begin{syntax}
|
\begin{syntax}
|
||||||
\slab{Static patterns} &\sP \in \SPatCat &::=& \sks \mid \sk \scons \sP\\
|
\slab{Static patterns} &\sP \in \SPatCat &::=& \sks \mid \sk \scons \sP\\
|
||||||
@@ -2682,8 +2645,8 @@ the following productions.
|
|||||||
\slab{Static computations} & \sM \in \SCompCat &::=& \sV \sapp \sW \mid \sV \dapp V \dapp W
|
\slab{Static computations} & \sM \in \SCompCat &::=& \sV \sapp \sW \mid \sV \dapp V \dapp W
|
||||||
\end{syntax}
|
\end{syntax}
|
||||||
%
|
%
|
||||||
The patterns comprise only static list destructing. We let $\sP$ range
|
The patterns comprise only static list deconstructing. We let $\sP$
|
||||||
over static patterns.
|
range over static patterns.
|
||||||
%
|
%
|
||||||
The static values comprise dynamic values, reflected dynamic values,
|
The static values comprise dynamic values, reflected dynamic values,
|
||||||
static lists, and static lambda abstractions. We let $\sV, \sW$ range
|
static lists, and static lambda abstractions. We let $\sV, \sW$ range
|
||||||
@@ -2706,8 +2669,8 @@ Static computations are subject to the following equational axioms.
|
|||||||
The first equation is static $\beta$-equivalence, it states that
|
The first equation is static $\beta$-equivalence, it states that
|
||||||
applying a static lambda abstraction with binder $\sks$ and body $\sM$
|
applying a static lambda abstraction with binder $\sks$ and body $\sM$
|
||||||
to a static value $\sV$ is equal to substituting $\sV$ for $\sks$ in
|
to a static value $\sV$ is equal to substituting $\sV$ for $\sks$ in
|
||||||
$\sM$. The second equation allows us to apply a static list
|
$\sM$. The second equation provides a means for applying a static
|
||||||
component-wise.
|
lambda abstraction to a static list component-wise.
|
||||||
%
|
%
|
||||||
\dhil{What about $\eta$-equivalence?}
|
\dhil{What about $\eta$-equivalence?}
|
||||||
|
|
||||||
@@ -2720,32 +2683,38 @@ $\reify \sV$ by induction on their structure.
|
|||||||
&\reify (\sV \scons \sW) \defas \reify \sV \dcons \reify \sW
|
&\reify (\sV \scons \sW) \defas \reify \sV \dcons \reify \sW
|
||||||
\ea
|
\ea
|
||||||
\]
|
\]
|
||||||
|
%
|
||||||
|
\dhil{Need to spell out that static pattern matching may induce dynamic (administrative) reductions}
|
||||||
|
%
|
||||||
\paragraph{Higher-order translation}
|
\paragraph{Higher-order translation}
|
||||||
The CPS translation is given in
|
%
|
||||||
|
The complete CPS translation is given in
|
||||||
Figure~\ref{fig:cps-higher-order-uncurried}. In essence, it is the
|
Figure~\ref{fig:cps-higher-order-uncurried}. In essence, it is the
|
||||||
same as the CPS translation for deep and shallow handlers we described
|
same as the refined first-order uncurried CPS translation, although
|
||||||
in Section~\ref{sec:pure-as-stack}, albeit separated into static and
|
the notation is slightly more involved due to the separation of static
|
||||||
dynamic parts. A major difference that has a large cosmetic effect on
|
and dynamic parts.
|
||||||
the presentation of the translation is that we maintain the invariant
|
|
||||||
that the statically known stack ($\sk$) always contains at least one
|
|
||||||
frame, consisting of a triple
|
|
||||||
$\sRecord{\reflect V_{fs}, \sRecord{\reflect V_{ret}, \reflect
|
|
||||||
V_{ops}}}$ of reflected dynamic pure frame stacks, return
|
|
||||||
handlers, and operation handlers. Maintaining this invariant ensures
|
|
||||||
that all translations are uniform in whether they appear statically
|
|
||||||
within the scope of a handler or not, and this simplifies our
|
|
||||||
correctness proof. To maintain the invariant, any place where a
|
|
||||||
dynamically known stack is passed in (as a continuation parameter
|
|
||||||
$k$), it is immediately decomposed using a dynamic language $\Let$ and
|
|
||||||
repackaged as a static value with reflected variable
|
|
||||||
names. Unfortunately, this does add some clutter to the translation
|
|
||||||
definition, as compared to the translations above. However, there is a
|
|
||||||
payoff in the removal of administrative reductions at run time.
|
|
||||||
%
|
%
|
||||||
\dhil{Rewrite the above.}
|
The translation on values is mostly homomorphic on the syntax
|
||||||
|
constructors, except for $\lambda$- and $\Lambda$-abstractions which
|
||||||
|
are translated in the exact same way, because the target calculus has
|
||||||
|
no notion of types. As per usual continuation passing style practice,
|
||||||
|
the translation of a lambda abstraction yields a dynamic binary lambda
|
||||||
|
abstraction, where the second parameter is intended to be the
|
||||||
|
continuation parameter. However, the translation slightly diverge from
|
||||||
|
the usual practice in the translation of the body as the result of
|
||||||
|
$\cps{M}$ is applied statically, rather than dynamically, to the
|
||||||
|
(reflected) continuation parameter.
|
||||||
%
|
%
|
||||||
|
The reason is that the translation on computations is staged: for any
|
||||||
|
given computation term the translation yields a static function, which
|
||||||
|
can be applied to a static continuation to ultimately produce a
|
||||||
|
$\UCalc$-computation term. This staging is key to eliminating static
|
||||||
|
administrative redexes as any static function may perform static
|
||||||
|
computation by manipulating its provided static continuation, as is
|
||||||
|
for instance done in the translation of $\Let$.
|
||||||
|
%
|
||||||
|
\dhil{Spell out why this translation qualifies as `higher-order'.}
|
||||||
|
|
||||||
Let us again revisit the example from
|
Let us again revisit the example from
|
||||||
Section~\ref{sec:first-order-curried-cps} to see that the higher-order
|
Section~\ref{sec:first-order-curried-cps} to see that the higher-order
|
||||||
translation eliminates the static redex at translation time.
|
translation eliminates the static redex at translation time.
|
||||||
@@ -2758,15 +2727,19 @@ translation eliminates the static redex at translation time.
|
|||||||
\end{equations}
|
\end{equations}
|
||||||
%
|
%
|
||||||
In contrast with the previous translations, the image of this
|
In contrast with the previous translations, the image of this
|
||||||
translation admits only a single dynamic reduction.
|
translation admits only a single dynamic reduction (disregarding the
|
||||||
|
dynamic administrative reductions arising from continuation
|
||||||
|
construction and deconstruction).
|
||||||
|
|
||||||
\subsubsection{Correctness}
|
\subsubsection{Correctness}
|
||||||
\label{sec:higher-order-cps-deep-handlers-correctness}
|
\label{sec:higher-order-cps-deep-handlers-correctness}
|
||||||
|
|
||||||
In order to prove the correctness of the higher-order uncurried CPS
|
We establish the correctness of the higher-order uncurried CPS
|
||||||
translation (Theorem~\ref{thm:ho-simulation}), we first state several
|
translation via a simulation result in style of
|
||||||
auxiliary lemmas describing how translated terms behave. First, the
|
Plotkin~\cite{Plotkin75} (Theorem~\ref{thm:ho-simulation}). However,
|
||||||
higher-order CPS translation commutes with substitution.
|
before we can state and prove this result, we first several auxiliary
|
||||||
|
lemmas describing how translated terms behave. First, the higher-order
|
||||||
|
CPS translation commutes with substitution.
|
||||||
%
|
%
|
||||||
\begin{lemma}[Substitution]\label{lem:ho-cps-subst}
|
\begin{lemma}[Substitution]\label{lem:ho-cps-subst}
|
||||||
%
|
%
|
||||||
@@ -2811,8 +2784,8 @@ It follows as a corollary that top-level substitution is well-behaved.
|
|||||||
Lemma~\ref{lem:ho-cps-subst}.
|
Lemma~\ref{lem:ho-cps-subst}.
|
||||||
\end{proof}
|
\end{proof}
|
||||||
%
|
%
|
||||||
In order to reason about the behaviour of the \semlab{Op} rule,
|
In order to reason about the behaviour \semlab{Op} rule, which is
|
||||||
which is defined in terms of an evaluation context, we extend the CPS
|
defined in terms of an evaluation context, we need to extend the CPS
|
||||||
translation to evaluation contexts.
|
translation to evaluation contexts.
|
||||||
%
|
%
|
||||||
\begin{equations}
|
\begin{equations}
|
||||||
@@ -2825,8 +2798,9 @@ translation to evaluation contexts.
|
|||||||
The following lemma is the characteristic property of the CPS
|
The following lemma is the characteristic property of the CPS
|
||||||
translation on evaluation contexts.
|
translation on evaluation contexts.
|
||||||
%
|
%
|
||||||
This allows us to focus on the computation contained within
|
It provides a means for decomposing an evaluation context, such that
|
||||||
an evaluation context.
|
we can focus on the computation contained within the evaluation
|
||||||
|
context.
|
||||||
%
|
%
|
||||||
\begin{lemma}[Decomposition]
|
\begin{lemma}[Decomposition]
|
||||||
\label{lem:decomposition}
|
\label{lem:decomposition}
|
||||||
@@ -2841,26 +2815,27 @@ an evaluation context.
|
|||||||
Proof by structural induction on the evaluation context $\EC$.
|
Proof by structural induction on the evaluation context $\EC$.
|
||||||
\end{proof}
|
\end{proof}
|
||||||
%
|
%
|
||||||
Though we have eliminated the static administrative redexes, we are
|
Even though we have eliminated the static administrative redexes, we
|
||||||
still left with one form of administrative redex that cannot be
|
still need to account for the dynamic administrative redexes that
|
||||||
eliminated statically because it only appears at run-time. These arise
|
arise from pattern matching against a reified continuation. To
|
||||||
from pattern matching against a reified stack of continuations and are
|
properly account for these administrative redexes it is convenient to
|
||||||
given by the $\usemlab{SplitList}$ rule.
|
treat list pattern matching as a primitive in $\UCalc$, therefore we
|
||||||
|
introduce a new reduction rule $\usemlab{SplitList}$ in $\UCalc$.
|
||||||
%
|
%
|
||||||
\begin{reductions}
|
\begin{reductions}
|
||||||
\usemlab{SplitList} & \Let\; (k \dcons ks) = V \dcons W \;\In\; M &\reducesto& M[V/k, W/ks] \\
|
\usemlab{SplitList} & \Let\; (k \dcons ks) = V \dcons W \;\In\; M &\reducesto& M[V/k, W/ks] \\
|
||||||
\end{reductions}
|
\end{reductions}
|
||||||
%
|
%
|
||||||
This is isomorphic to the \usemlab{Split} rule, but we now treat lists
|
Note this rule is isomorphic to the \usemlab{Split} rule with lists
|
||||||
and \usemlab{SplitList} as distinct from pairs, unit, and
|
encoded as right nested pairs using unit to denote nil.
|
||||||
\usemlab{Split} in the higher-order translation so that we can
|
|
||||||
properly account for administrative reduction.
|
|
||||||
%
|
%
|
||||||
We write $\areducesto$ for the compatible closure of
|
We write $\areducesto$ for the compatible closure of
|
||||||
\usemlab{SplitList}.
|
\usemlab{SplitList}.
|
||||||
|
|
||||||
By definition, $\reify \reflect V = V$, but we also need to reason
|
We also need to be able to reason about the computational content of
|
||||||
about the inverse composition.
|
reflection after reification. By definition we have that
|
||||||
|
$\reify \reflect V = V$, the following lemma lets us reason about the
|
||||||
|
inverse composition.
|
||||||
%
|
%
|
||||||
\begin{lemma}[Reflect after reify]
|
\begin{lemma}[Reflect after reify]
|
||||||
\label{lem:reflect-after-reify}
|
\label{lem:reflect-after-reify}
|
||||||
@@ -2917,10 +2892,10 @@ Follows from Lemmas~\ref{lem:decomposition},
|
|||||||
\ref{lem:reflect-after-reify}, and \ref{lem:forwarding}.
|
\ref{lem:reflect-after-reify}, and \ref{lem:forwarding}.
|
||||||
\end{proof}
|
\end{proof}
|
||||||
%
|
%
|
||||||
We now turn to our main result which is a simulation result in style
|
Finally, we have the ingredients to state and prove the simulation
|
||||||
of Plotkin~\cite{Plotkin75}. The theorem shows that the only extra
|
result. The following theorem shows that the only extra behaviour
|
||||||
behaviour exhibited by a translated term is the bureaucracy of
|
exhibited by a translated term is the bureaucracy of deconstructing
|
||||||
deconstructing the continuation stack.
|
the continuation stack.
|
||||||
%
|
%
|
||||||
\begin{theorem}[Simulation]
|
\begin{theorem}[Simulation]
|
||||||
\label{thm:ho-simulation}
|
\label{thm:ho-simulation}
|
||||||
@@ -2933,18 +2908,18 @@ If $M \reducesto N$ then $\pcps{M} \reducesto^+ \areducesto^* \pcps{N}$.
|
|||||||
follows from Lemma~\ref{lem:handle-op}.
|
follows from Lemma~\ref{lem:handle-op}.
|
||||||
\end{proof}
|
\end{proof}
|
||||||
%
|
%
|
||||||
In common with most CPS translations, full abstraction does not
|
% In common with most CPS translations, full abstraction does not
|
||||||
hold. However, as our semantics is deterministic it is straightforward
|
% hold. However, as our semantics is deterministic it is straightforward
|
||||||
to show a backward simulation result.
|
% to show a backward simulation result.
|
||||||
%
|
% %
|
||||||
\begin{corollary}[Backwards simulation]
|
% \begin{corollary}[Backwards simulation]
|
||||||
If $\pcps{M} \reducesto^+ \areducesto^* V$ then there exists $W$ such that
|
% If $\pcps{M} \reducesto^+ \areducesto^* V$ then there exists $W$ such that
|
||||||
$M \reducesto^* W$ and $\pcps{W} = V$.
|
% $M \reducesto^* W$ and $\pcps{W} = V$.
|
||||||
\end{corollary}
|
% \end{corollary}
|
||||||
%
|
% %
|
||||||
\begin{proof}
|
% \begin{proof}
|
||||||
TODO\dots
|
% TODO\dots
|
||||||
\end{proof}
|
% \end{proof}
|
||||||
%
|
%
|
||||||
\chapter{Abstract machine semantics}
|
\chapter{Abstract machine semantics}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user