mirror of
https://github.com/dhil/phd-dissertation
synced 2026-03-13 11:08:25 +00:00
Discussion about continuation deconstruction.
This commit is contained in:
213
thesis.tex
213
thesis.tex
@@ -2286,15 +2286,13 @@ unviable in practice.
|
|||||||
|
|
||||||
The following minimal example readily illustrates both issues.
|
The following minimal example readily illustrates both issues.
|
||||||
%
|
%
|
||||||
\begin{equations}
|
\begin{align*}
|
||||||
\pcps{\Return\;\Record{}}
|
\pcps{\Return\;\Record{}}
|
||||||
&= & (\lambda k.k\,\Record{})\,(\lambda x.\lambda h.x)\,(\lambda \Record{z,\_}.\Absurd\,z) \\
|
= & (\lambda k.k\,\Record{})\,(\lambda x.\lambda h.x)\,(\lambda \Record{z,\_}.\Absurd\,z) \\
|
||||||
&\reducesto& ((\lambda x.\lambda h.x)\,\Record{})\,(\lambda \Record{z,\_}.\Absurd\,z) \\
|
\reducesto& ((\lambda x.\lambda h.x)\,\Record{})\,(\lambda \Record{z,\_}.\Absurd\,z) \numberthis\label{eq:cps-admin-reduct-1}\\
|
||||||
&\reducesto& (\lambda h.\Record{})\,(\lambda \Record{z,\_}.\Absurd\,z) \numberthis\label{eq:cps-admin-reduct} \\
|
\reducesto& (\lambda h.\Record{})\,(\lambda \Record{z,\_}.\Absurd\,z) \numberthis\label{eq:cps-admin-reduct-2}\\
|
||||||
&\reducesto& \Record{} \\
|
\reducesto& \Record{}
|
||||||
\end{equations}
|
\end{align*}
|
||||||
%
|
|
||||||
\dhil{Mark the second reduction, so that it can be referred back to}
|
|
||||||
%
|
%
|
||||||
The second and third reductions simulate handling $\Return\;\Record{}$
|
The second and third reductions simulate handling $\Return\;\Record{}$
|
||||||
at the top level. The second reduction partially applies the curried
|
at the top level. The second reduction partially applies the curried
|
||||||
@@ -2477,7 +2475,7 @@ refined translation makes the example properly tail-recursive.
|
|||||||
\begin{equations}
|
\begin{equations}
|
||||||
\pcps{\Return\;\Record{}}
|
\pcps{\Return\;\Record{}}
|
||||||
&= & (\lambda (k \cons ks).k\,\Record{}\,ks)\,((\lambda x.\lambda ks.x) \cons (\lambda \Record{z, \_}.\lambda ks.\Absurd\,z) \cons \nil) \\
|
&= & (\lambda (k \cons ks).k\,\Record{}\,ks)\,((\lambda x.\lambda ks.x) \cons (\lambda \Record{z, \_}.\lambda ks.\Absurd\,z) \cons \nil) \\
|
||||||
&\reducesto& (\lambda x.\lambda ks.x)\,\Record{}\,((\lambda \Record{z,\_}.\lambda ks.\Absurd\,z) \cons \nil) \numberthis\label{eq:cps-admin-reduct-2}\\
|
&\reducesto& (\lambda x.\lambda ks.x)\,\Record{}\,((\lambda \Record{z,\_}.\lambda ks.\Absurd\,z) \cons \nil)\\
|
||||||
&\reducesto& \Record{}
|
&\reducesto& \Record{}
|
||||||
\end{equations}
|
\end{equations}
|
||||||
%
|
%
|
||||||
@@ -2485,11 +2483,11 @@ The reduction sequence in the image of this uncurried translation has
|
|||||||
one fewer steps (disregarding the administrative steps induced by
|
one fewer steps (disregarding the administrative steps induced by
|
||||||
pattern matching) than in the image of the curried translation. The
|
pattern matching) than in the image of the curried translation. The
|
||||||
`missing' step is precisely the reduction marked
|
`missing' step is precisely the reduction marked
|
||||||
(\ref{eq:cps-admin-reduct}), which was a partial application of the
|
\eqref{eq:cps-admin-reduct-2}, which was a partial application of the
|
||||||
initial pure continuation function that was not in tail
|
initial pure continuation function that was not in tail
|
||||||
position. Note, however, that the first reduction
|
position. Note, however, that the first reduction (corresponding to
|
||||||
(\ref{eq:cps-admin-reduct-2}) remains administrative, the reduction is
|
\eqref{eq:cps-admin-reduct-1}) remains administrative, the reduction
|
||||||
entirely static, and as such, it can be dealt with as part of the
|
is entirely static, and as such, it can be dealt with as part of the
|
||||||
translation.
|
translation.
|
||||||
%
|
%
|
||||||
|
|
||||||
@@ -2826,7 +2824,8 @@ pure continuation are few. We can derive the all possible
|
|||||||
instantiations systematically by using the operational semantics of
|
instantiations systematically by using the operational semantics of
|
||||||
$\HCalc$. According to the operational semantics the continuation of a
|
$\HCalc$. According to the operational semantics the continuation of a
|
||||||
$\Return$-computation is either the continuation of a
|
$\Return$-computation is either the continuation of a
|
||||||
$\Let$-expression or a $\Return$-clause.
|
$\Let$-expression or a $\Return$-clause (a bare top-level
|
||||||
|
$\Return$-computation is handled by the $\pcps{-}$ translation).
|
||||||
%
|
%
|
||||||
The translations of $\Let$-expressions and $\Return$-clauses each
|
The translations of $\Let$-expressions and $\Return$-clauses each
|
||||||
account for odd continuations. For example, the translation of $\Let$
|
account for odd continuations. For example, the translation of $\Let$
|
||||||
@@ -2915,161 +2914,6 @@ continuation structure. The forwarding branch also deconstructs the
|
|||||||
continuation, but for a different purpose; it augments the resumption
|
continuation, but for a different purpose; it augments the resumption
|
||||||
$\dhkr$ with the next pure and effect continuation functions.
|
$\dhkr$ with the next pure and effect continuation functions.
|
||||||
|
|
||||||
% The translation of
|
|
||||||
% $\Handle$ applies the translation of $M$ to the current continuation
|
|
||||||
% extended with the translation of the $\Return$-clause, acting as a
|
|
||||||
% pure continuation function, and the translation of operation-clauses,
|
|
||||||
% acting as an effect continuation function.
|
|
||||||
|
|
||||||
% The translation on values is almost homomorphic on the syntax
|
|
||||||
% constructors. The notable exceptions are the translations of
|
|
||||||
% $\lambda$-abstractions and $\Lambda$-abstractions. The former gives
|
|
||||||
% rise to dynamic computation at runtime, and thus, the translation
|
|
||||||
% emits a dynamic $\dlam$-abstraction with two formal parameters: the
|
|
||||||
% function parameter, $x$, and the continuation parameter, $ks$. The
|
|
||||||
% body of the $\dlam$-abstraction is somewhat anomalous as the
|
|
||||||
% continuation $ks$ is subject to immediate dynamic deconstruction just
|
|
||||||
% to be reconstructed again and used as a static argument to the
|
|
||||||
% translation of the original body computation $M$. This deconstruction
|
|
||||||
% and reconstruction may at first glance appear to be rather pointless,
|
|
||||||
% however, a closer look reveals that it performs a critical role as it
|
|
||||||
% ensures that the translation on computation terms has immediate access
|
|
||||||
% to the next pure and effect continuation functions. In fact, the
|
|
||||||
% translation is set up such that every generated dynamic
|
|
||||||
% $\dlam$-abstraction deconstructs its continuation argument
|
|
||||||
% appropriately to expose just enough (static) continuation structure in
|
|
||||||
% order to guarantee that static pattern matching never fails.
|
|
||||||
% %
|
|
||||||
% (The translation is somewhat unsatisfactory regarding this
|
|
||||||
% deconstruction of dynamic continuations as the various generated
|
|
||||||
% dynamic lambda abstractions do not deconstruct their continuation
|
|
||||||
% arguments uniformly.)
|
|
||||||
% %
|
|
||||||
% Since the target language is oblivious to types any
|
|
||||||
% $\Lambda$-abstraction gets translated in a similar way to
|
|
||||||
% $\lambda$-abstraction, where the first parameter becomes a placeholder
|
|
||||||
% for a ``dummy'' unit argument.
|
|
||||||
|
|
||||||
% The translation of computation terms is more interesting. Note the
|
|
||||||
% type of the translation function,
|
|
||||||
% $\cps{-} : \CompCat \to \SValCat^\ast \to \UCompCat$. It is a binary
|
|
||||||
% function, taking a $\HCalc$-computation term as its first argument and
|
|
||||||
% a static continuation as its second argument, and ultimately produces
|
|
||||||
% a $\UCalc$-computation term. The static continuation may be
|
|
||||||
% manipulated during the translation as is done in the translations of
|
|
||||||
% $\Return$, $\Let$, $\Do$, and $\Handle$. The translation of $\Return$
|
|
||||||
% consumes the next pure continuation function $\sk$ and applies it
|
|
||||||
% dynamically to the translation of $V$ and the reified remainder,
|
|
||||||
% $\sks$, of the static continuation. Keep in mind that the translation
|
|
||||||
% of $\Return$ only consumes one of the two guaranteed available
|
|
||||||
% continuation functions from the provided continuation argument; as a
|
|
||||||
% consequence the next continuation function in $\sks$ is an effect
|
|
||||||
% continuation. This consequence is accounted for in the translations of
|
|
||||||
% $\Let$ and $\Return$-clauses, which are precisely the two possible
|
|
||||||
% (dynamic) origins of $\sk$. For instance, the translation of $\Let$
|
|
||||||
% consumes the current pure continuation function and generates a
|
|
||||||
% replacement: a pure continuation function which expects an odd dynamic
|
|
||||||
% continuation $ks$, which it deconstructs to expose the effect
|
|
||||||
% continuation $h$ along with the current pure continuation function in
|
|
||||||
% the translation of $N$. The modified continuation is passed to the
|
|
||||||
% translation of $M$.
|
|
||||||
% %
|
|
||||||
% To provide a flavour of how this continuation manipulation functions
|
|
||||||
% in practice, consider the following example term.
|
|
||||||
% %
|
|
||||||
% \begin{derivation}
|
|
||||||
% &\pcps{\Let\;x \revto \Return\;V\;\In\;N}\\
|
|
||||||
% =& \reason{definition of $\pcps{-}$}\\
|
|
||||||
% &\ba[t]{@{}l}(\slam \sk \scons \sks.\cps{\Return\;V} \sapp
|
|
||||||
% (\reflect(\dlam x\,ks.
|
|
||||||
% \ba[t]{@{}l}
|
|
||||||
% \Let\;(h \dcons ks') = ks \;\In\\
|
|
||||||
% \cps{N} \sapp (\sk \scons \reflect h \scons \reflect ks')) \scons \sks)
|
|
||||||
% \ea\\
|
|
||||||
% \sapp (\reflect (\dlam x\,ks.x) \scons \reflect (\dlam z\,ks.\Absurd~z) \scons \snil))
|
|
||||||
% \ea\\
|
|
||||||
% =& \reason{definition of $\cps{-}$}\\
|
|
||||||
% &\ba[t]{@{}l}(\slam \sk \scons \sks.(\slam \sk \scons \sks. \reify \sk \dapp \cps{V} \dapp \reify \sks) \sapp
|
|
||||||
% (\reflect(\dlam x\,ks.
|
|
||||||
% \ba[t]{@{}l}
|
|
||||||
% \Let\;(h \dcons ks') = ks \;\In\\
|
|
||||||
% \cps{N} \sapp (\sk \scons \reflect h \scons \reflect ks')) \scons \sks)
|
|
||||||
% \ea\\
|
|
||||||
% \sapp (\reflect (\dlam x\,ks.x) \scons \reflect (\dlam z\,ks.\Absurd~z) \scons \snil))
|
|
||||||
% \ea\\
|
|
||||||
% =& \reason{static $\beta$-reduction}\\
|
|
||||||
% &(\slam \sk \scons \sks. \reify \sk \dapp \cps{V} \dapp \reify \sks)
|
|
||||||
% \sapp
|
|
||||||
% (\reflect(\dlam x\,\dhk.
|
|
||||||
% \ba[t]{@{}l}
|
|
||||||
% \Let\;(h \dcons \dhk') = \dhk \;\In\\
|
|
||||||
% \cps{N} \sapp
|
|
||||||
% \ba[t]{@{}l}
|
|
||||||
% (\reflect (\dlam x\,\dhk.x) \scons \reflect h \scons \reflect \dhk'))\\
|
|
||||||
% ~~\scons \reflect (\dlam z\,\dhk.\Absurd~z) \scons \snil))
|
|
||||||
% \ea
|
|
||||||
% \ea\\
|
|
||||||
% =& \reason{static $\beta$-reduction}\\
|
|
||||||
% &\ba[t]{@{}l@{~}l}
|
|
||||||
% &(\dlam x\,\dhk.
|
|
||||||
% \Let\;(h \dcons \dhk') = \dhk \;\In\;
|
|
||||||
% \cps{N} \sapp
|
|
||||||
% (\reflect (\dlam x\,\dhk.x) \scons \reflect h \scons \reflect \dhk'))\\
|
|
||||||
% \dapp& \cps{V} \dapp ((\dlam z\,\dhk.\Absurd~z) \dcons \dnil)\\
|
|
||||||
% \ea\\
|
|
||||||
% \reducesto& \reason{\usemlab{App_2}}\\
|
|
||||||
% &\Let\;(h \dcons \dhk') = (\dlam z\,\dhk.\Absurd~z) \dcons \dnil \;\In\;
|
|
||||||
% \cps{N[V/x]} \sapp
|
|
||||||
% (\reflect (\dlam x\,\dhk.x) \scons \reflect h \scons \reflect \dhk'))\\
|
|
||||||
% \reducesto^+& \reason{dynamic pattern matching and substitution}\\
|
|
||||||
% &\cps{N[V/x]} \sapp
|
|
||||||
% (\reflect (\dlam x\,\dhk.x) \scons \reflect (\dlam z\,\dhk.\Absurd~z) \scons \reflect \dnil)
|
|
||||||
% \end{derivation}
|
|
||||||
% %
|
|
||||||
% The translation of $\Return$ provides the generated dynamic pure
|
|
||||||
% continuation function with the odd continuation
|
|
||||||
% $((\dlam z\,ks.\Absurd~z) \dcons \dnil)$. After the \usemlab{App_2}
|
|
||||||
% reduction, the pure continuation function deconstructs the odd
|
|
||||||
% continuation in order to bind the current effect continuation function
|
|
||||||
% to the name $h$, which would have been used during the translation of
|
|
||||||
% $N$.
|
|
||||||
|
|
||||||
% The translation of $\Do$ consumes both the current pure continuation
|
|
||||||
% function and current effect continuation function. It applies the
|
|
||||||
% effect continuation function dynamically to an operation package and
|
|
||||||
% the reified remainder of the continuation. As usual, the operation
|
|
||||||
% package contains the payload and the resumption, which is a reversed
|
|
||||||
% slice of the provided continuation. The translation of $\Handle$
|
|
||||||
% applies the translation of $M$ to the current continuation extended
|
|
||||||
% with the translation of the $\Return$-clause, acting as a pure
|
|
||||||
% continuation function, and the translation of operation-clauses,
|
|
||||||
% acting as an effect continuation function.
|
|
||||||
|
|
||||||
% The translation of a return clause $\hret$ of some handler $H$
|
|
||||||
% generates a dynamic lambda abstraction, which expects an odd
|
|
||||||
% continuation. In its body it extracts three elements from the
|
|
||||||
% continuation parameter $ks$. The first element is discarded as it is
|
|
||||||
% the effect continuation corresponding to the translation of
|
|
||||||
% $\hops$. The other two elements are used to statically expose the next
|
|
||||||
% pure and effect continuation functions in the translation of $N$.
|
|
||||||
% %
|
|
||||||
% The translation of $\hops$ also generates a dynamic lambda
|
|
||||||
% abstraction, which unpacks the operation package to perform a
|
|
||||||
% case-split on the operation label $z$. The continuation $ks$ is
|
|
||||||
% deconstructed in the branch for $\ell$ in order to expose the
|
|
||||||
% continuation structure. The forwarding branch also deconstructs the
|
|
||||||
% continuation, however, for a different purpose, namely, to augment the
|
|
||||||
% resumption $rs$ the next pure and effect continuation functions.
|
|
||||||
%
|
|
||||||
\dhil{Remark that an alternative to cluttering the translations with
|
|
||||||
unpacking and repacking of continuations would be to make static
|
|
||||||
pattern generate dynamic let bindings whenever necessary. While it
|
|
||||||
may reduce the dynamic administrative reductions, it makes the
|
|
||||||
simulation proof more complicated.}
|
|
||||||
|
|
||||||
%
|
|
||||||
\dhil{Spell out why this translation qualifies as `higher-order'.}
|
|
||||||
|
|
||||||
Let us revisit the example from
|
Let us 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.
|
||||||
@@ -3081,10 +2925,33 @@ translation eliminates the static redex at translation time.
|
|||||||
&\reducesto& \Record{}
|
&\reducesto& \Record{}
|
||||||
\end{equations}
|
\end{equations}
|
||||||
%
|
%
|
||||||
In contrast with the previous translations, the image of this
|
In contrast with the previous translations, the reduction sequence in
|
||||||
translation admits only a single dynamic reduction (disregarding the
|
the image of this translation contains only a single dynamic reduction
|
||||||
dynamic administrative reductions arising from continuation
|
(disregarding the dynamic administrative reductions arising from
|
||||||
construction and deconstruction).
|
continuation construction and deconstruction); both
|
||||||
|
\eqref{eq:cps-admin-reduct-1} and \eqref{eq:cps-admin-reduct-2}
|
||||||
|
reductions have been eliminated as part of the translation.
|
||||||
|
|
||||||
|
\paragraph{Implicit lazy continuation deconstruction}
|
||||||
|
%
|
||||||
|
An alternative to the explicit deconstruction of continuations is to
|
||||||
|
implicitly deconstruct continuations on demand when static pattern
|
||||||
|
matching fails. This was the approach taken by
|
||||||
|
\citet*{HillerstromLAS17}. On one hand this approach leads to a
|
||||||
|
slightly slicker presentation. On the other hand it complicates the
|
||||||
|
proof of correctness as one must account for static pattern matching
|
||||||
|
failure.
|
||||||
|
%
|
||||||
|
A practical argument in favour of the explicit eager continuation
|
||||||
|
deconstruction is that it is more accessible from an implementation
|
||||||
|
point of view. No implementation details are hidden away in side
|
||||||
|
conditions.
|
||||||
|
%
|
||||||
|
Furthermore, it is not clear that lazy deconstruction has any
|
||||||
|
advantage over eager deconstruction, as the translation must reify the
|
||||||
|
continuation when it transitions from computations to values and
|
||||||
|
reflect the continuation when it transitions from values to
|
||||||
|
computations, in which case static pattern matching would fail.
|
||||||
|
|
||||||
\subsubsection{Correctness}
|
\subsubsection{Correctness}
|
||||||
\label{sec:higher-order-cps-deep-handlers-correctness}
|
\label{sec:higher-order-cps-deep-handlers-correctness}
|
||||||
|
|||||||
Reference in New Issue
Block a user