mirror of
https://github.com/dhil/phd-dissertation
synced 2026-03-13 02:58:26 +00:00
Fix typos in introduction
This commit is contained in:
149
thesis.tex
149
thesis.tex
@@ -611,16 +611,33 @@ efficiency.
|
||||
% expressiveness.
|
||||
|
||||
\section{Why first-class control matters}
|
||||
First things first, let us settle on the meaning of the qualifier
|
||||
`first-class'. A programming language entity (or citizen) is regarded
|
||||
as being first-class if it can be used on an equal footing with other
|
||||
entities.
|
||||
%
|
||||
A familiar example is functions as first-class values. A first-class
|
||||
function may be treated like any other primitive value, i.e. passed as
|
||||
an argument to other functions, returned from functions, stored in
|
||||
data structures, or let-bound.
|
||||
|
||||
First-class control makes the control state of the program available
|
||||
as a first-class value known as a continuation object at any point
|
||||
during evaluation~\cite{FriedmanHK84}. This object comes equipped with
|
||||
at least one operation for restoring the control state. As such the
|
||||
control flow of the program becomes a first-class entity that the
|
||||
programmer may manipulate to implement interesting control phenomena.
|
||||
|
||||
From the perspective of programmers first-class control is a valuable
|
||||
programming feature because it enables them to implement their own
|
||||
control idioms as if they were native to the programming language (in
|
||||
fact this is the very definition of first-class control). More
|
||||
important, with first-class control programmer-defined control idioms
|
||||
are local phenomena which can be encapsulated in a library such that
|
||||
the rest of the program does not need to be made aware of their
|
||||
existence. Conversely, without first-class control some control idioms
|
||||
can only be implemented using global program restructuring techniques
|
||||
such as continuation passing style.
|
||||
control idioms, such as async/await~\cite{SymePL11}, as if they were
|
||||
native to the programming language. More important, with first-class
|
||||
control programmer-defined control idioms are local phenomena which
|
||||
can be encapsulated in a library such that the rest of the program
|
||||
does not need to be made aware of their existence. Conversely, without
|
||||
first-class control some control idioms can only be implemented using
|
||||
global program restructuring techniques such as continuation passing
|
||||
style.
|
||||
|
||||
From the perspective of compiler engineers first-class control is
|
||||
valuable because it unifies several control-related constructs under
|
||||
@@ -678,9 +695,12 @@ intended purpose.
|
||||
|
||||
In contrast, effect handlers provide a structured form of delimited
|
||||
control, where programmers can give distinct names to control reifying
|
||||
operations and separate the from their handling.
|
||||
operations and separate them from their handling. Throughout this
|
||||
dissertation we will see numerous examples of how effect handlers
|
||||
makes programming with delimited structured (c.f. the following
|
||||
section, Chapter~\ref{ch:continuations}, and
|
||||
Chapter~\ref{ch:unary-handlers}).
|
||||
%
|
||||
\dhil{Maybe expand this a bit more to really sell it}
|
||||
|
||||
\section{State of effectful programming}
|
||||
\label{sec:state-of-effprog}
|
||||
@@ -690,7 +710,8 @@ boxes, whose outputs are determined entirely by their
|
||||
inputs~\cite{Hughes89,Howard80}. This is a compelling view which
|
||||
admits a canonical mathematical model of
|
||||
computation~\cite{Church32,Church41}. Alas, this view does not capture
|
||||
the reality of practical programs, which interact their environment.
|
||||
the reality of practical programs, which interact with their
|
||||
environment.
|
||||
%
|
||||
Functional programming prominently features two distinct, but related,
|
||||
approaches to effectful programming, which \citet{Filinski96}
|
||||
@@ -705,11 +726,11 @@ style~\cite{JonesW93}. The latter retains the usual direct style of
|
||||
programming either by hard-wiring the semantics of the effects into
|
||||
the language or by more flexible means via first-class control.
|
||||
|
||||
In this section I will provide a brief programming perspective on
|
||||
different approaches to programming with effects along with an
|
||||
informal introduction to the related concepts. We will look at each
|
||||
approach through the lens of global mutable state --- which is the
|
||||
``hello world'' example of effectful programming.
|
||||
In this section I will provide a brief perspective on different
|
||||
approaches to programming with effects along with an informal
|
||||
introduction to the related concepts. We will look at each approach
|
||||
through the lens of global mutable state --- the ``hello world'' of
|
||||
effectful programming.
|
||||
|
||||
% how
|
||||
% effectful programming has evolved as well as providing an informal
|
||||
@@ -730,9 +751,9 @@ approach through the lens of global mutable state --- which is the
|
||||
%
|
||||
We can realise stateful behaviour by either using language-supported
|
||||
state primitives, globally structure our program to follow a certain
|
||||
style, or use first-class control in the form of delimited control to
|
||||
simulate state. We do not consider undelimited control, because it is
|
||||
insufficient to express mutable state~\cite{FriedmanS00}.
|
||||
style, or using first-class control in the form of delimited control
|
||||
to simulate state. We do not consider undelimited control, because it
|
||||
is insufficient to express mutable state~\cite{FriedmanS00}.
|
||||
% Programming in its infancy was effectful as the idea of first-class
|
||||
% control was conceived already during the design of the programming
|
||||
% language Algol~\cite{BackusBGKMPRSVWWW60} -- one of the early
|
||||
@@ -777,13 +798,14 @@ It is common to find mutable state builtin into the semantics of
|
||||
mainstream programming languages. However, different languages vary in
|
||||
their approach to mutable state. For instance, state mutation
|
||||
underpins the foundations of imperative programming languages
|
||||
belonging to the C family of languages. They do typically not
|
||||
belonging to the C family of languages. They typically do not
|
||||
distinguish between mutable and immutable values at the level of
|
||||
types. Contrary, programming languages belonging to the ML family of
|
||||
languages use types to differentiate between mutable and immutable
|
||||
values. They reflect mutable values in types by using a special unary
|
||||
type constructor $\PCFRef^{\Type \to \Type}$. Furthermore, ML
|
||||
languages equip the $\PCFRef$ constructor with three operations.
|
||||
types. On the contrary, programming languages belonging to the ML
|
||||
family of languages use types to differentiate between mutable and
|
||||
immutable values. They reflect mutable values in types by using a
|
||||
special unary type constructor $\PCFRef^{\Type \to
|
||||
\Type}$. Furthermore, ML languages equip the $\PCFRef$ constructor
|
||||
with three operations.
|
||||
%
|
||||
\[
|
||||
\refv : S \to \PCFRef~S \qquad\quad
|
||||
@@ -815,7 +837,7 @@ The body of the function first retrieves the current value of the
|
||||
state cell and binds it to $st$. Subsequently, it destructively
|
||||
increments the value of the state cell. Finally, it applies the
|
||||
predicate $\even : \Int \to \Bool$ to the original state value to test
|
||||
whether its parity is even (remark: this example function is a slight
|
||||
whether its parity is even (this example function is a slight
|
||||
variation of an example by \citet{Gibbons12}).
|
||||
%
|
||||
We can run this computation as a subcomputation in the context of
|
||||
@@ -913,8 +935,9 @@ represents the continuation of the invocation of $\shift$ (up to the
|
||||
innermost reset); it gets passed as a function to the argument of
|
||||
$\shift$.
|
||||
|
||||
Both primitives are defined over some (globally) fixed result type
|
||||
$R$.
|
||||
We define both primitives over some fixed return type $R$ (an actual
|
||||
practical implementation would use polymorphism to make them more
|
||||
flexible).
|
||||
%
|
||||
By instantiating $R = S \to A \times S$, where $S$ is the type of
|
||||
state and $A$ is the type of return values, then we can use shift and
|
||||
@@ -970,11 +993,12 @@ Modulo naming of operations, this version is similar to the version
|
||||
that uses builtin state. The type signature of the function is even
|
||||
the same.
|
||||
%
|
||||
Before we can apply this function we must first a state initialiser.
|
||||
Before we can apply this function we must first implement a state
|
||||
initialiser.
|
||||
%
|
||||
\[
|
||||
\bl
|
||||
\runState : (\UnitType \to R) \to S \to R \times S\\
|
||||
\runState : (\UnitType \to A) \to S \to A \times S\\
|
||||
\runState~m~st_0 \defas \reset{\lambda\Unit.\Let\;x \revto m\,\Unit\;\In\;\lambda st. \Record{x;st}}\,st_0
|
||||
\bl
|
||||
\el
|
||||
@@ -994,7 +1018,7 @@ the state-accepting function returned by the reset instance. The
|
||||
application of the reset instance to $st_0$ effectively causes
|
||||
evaluation of each function in this chain to start.
|
||||
|
||||
After instantiating $R = \Bool$ and $S = \Int$ we can use the
|
||||
After instantiating $A = \Bool$ and $S = \Int$ we can use the
|
||||
$\runState$ function to apply the $\incrEven$ function.
|
||||
%
|
||||
\[
|
||||
@@ -1056,8 +1080,8 @@ Haskell~\cite{JonesABBBFHHHHJJLMPRRW99}.
|
||||
\el
|
||||
\]
|
||||
%
|
||||
Interactions between $\Return$ and $\bind$ are governed by the
|
||||
so-called `monad laws'.
|
||||
Interactions between $\Return$ and $\bind$ are governed by the monad
|
||||
laws.
|
||||
\begin{reductions}
|
||||
\slab{Left\textrm{ }identity} & \Return\;x \bind k &=& k~x\\
|
||||
\slab{Right\textrm{ }identity} & m \bind \Return &=& m\\
|
||||
@@ -1397,7 +1421,7 @@ operation is another computation tree node.
|
||||
%
|
||||
\[
|
||||
\bl
|
||||
\ba{@{~}l@{\qquad}@{~}r}
|
||||
\ba{@{~}l@{\,\quad}@{~}r}
|
||||
\multicolumn{2}{l}{T~A \defas \Free~F~A} \smallskip\\
|
||||
\multirow{2}{*}{
|
||||
\bl
|
||||
@@ -1894,10 +1918,13 @@ polymorphic $\lambda$-calculi for which I give computational
|
||||
interpretations in terms of contextual operational semantics and
|
||||
realise using two foundational operational techniques: continuation
|
||||
passing style and abstract machine semantics. When it comes to
|
||||
expressivity studies there are multiple complementary notions of
|
||||
expressiveness available in the literature; in this dissertation I
|
||||
work with typed macro-expressiveness and type-respecting
|
||||
expressiveness notions.
|
||||
expressiveness there are multiple possible dimensions to investigate
|
||||
and multiple different notions of expressivity available. I focus on
|
||||
two questions: `are deep, shallow, and parameterised handlers
|
||||
interdefinable?' which I investigate via a syntactic notion of
|
||||
expressiveness due \citet{Felleisen91}. And, `does effect handlers
|
||||
admit any essential computational efficiency?' which I investigate
|
||||
using a semantic notion of expressiveness due to \citet{LongleyN15}.
|
||||
|
||||
\subsection{Scope extrusion}
|
||||
The literature on effect handlers is rich, and my dissertation is but
|
||||
@@ -1941,8 +1968,11 @@ theory of scoped effect operations, whilst \citet{BiernackiPPS20}
|
||||
study them in conjunction with ordinary handlers from a programming
|
||||
perspective.
|
||||
|
||||
% \citet{WuSH14} study scoped effects, which are effects whose payloads
|
||||
% are effectful computations
|
||||
% \citet{WuSH14} study scoped effects, which are effects whose
|
||||
% payloads are effectful computations. Scoped effects are
|
||||
% non-algebraic, Thinking in terms of computation trees, a scoped
|
||||
% effect is not an internal node of some computation tree, rather, it
|
||||
% is itself a whole computation tree.
|
||||
|
||||
% Effect handlers were conceived in the realm of category theory to give
|
||||
% an algebraic treatment of exception handling~\cite{PlotkinP09}. They
|
||||
@@ -1963,9 +1993,9 @@ handlers extension to Prolog; and \citet{Leijen17b} has an imperative
|
||||
take on effect handlers in C.
|
||||
|
||||
\section{Contributions}
|
||||
The key contributions of this dissertation are scattered across the
|
||||
four main parts. The following listing summarises the contributions of
|
||||
each part.
|
||||
The key contributions of this dissertation are spread across the four
|
||||
main parts. The following listing summarises the contributions of each
|
||||
part.
|
||||
\paragraph{Background}
|
||||
\begin{itemize}
|
||||
\item A comprehensive operational characterisation of various
|
||||
@@ -2010,35 +2040,40 @@ The following is a summary of the chapters belonging to each part of
|
||||
this dissertation.
|
||||
|
||||
\paragraph{Background}
|
||||
Chapter~\ref{ch:maths-prep} defines some basic mathematical
|
||||
\begin{itemize}
|
||||
\item Chapter~\ref{ch:maths-prep} defines some basic mathematical
|
||||
notation and constructions that are they pervasively throughout this
|
||||
dissertation.
|
||||
|
||||
Chapter~\ref{ch:continuations} presents a literature survey of
|
||||
\item Chapter~\ref{ch:continuations} presents a literature survey of
|
||||
continuations and first-class control. I classify continuations
|
||||
according to their operational behaviour and provide an overview of
|
||||
the various first-class sequential control operators that appear in
|
||||
the literature. The application spectrum of continuations is discussed
|
||||
as well as implementation strategies for first-class control.
|
||||
\end{itemize}
|
||||
|
||||
\paragraph{Programming}
|
||||
Chapter~\ref{ch:base-language} introduces a polymorphic fine-grain
|
||||
\begin{itemize}
|
||||
\item Chapter~\ref{ch:base-language} introduces a polymorphic fine-grain
|
||||
call-by-value core calculus, $\BCalc$, which makes key use of
|
||||
\citeauthor{Remy93}-style row polymorphism to implement polymorphic
|
||||
variants, structural records, and a structural effect system. The
|
||||
calculus distils the essence of the core of the Links programming
|
||||
language.
|
||||
|
||||
Chapter~\ref{ch:unary-handlers} presents three extensions of $\BCalc$,
|
||||
\item Chapter~\ref{ch:unary-handlers} presents three extensions of $\BCalc$,
|
||||
which are $\HCalc$ that adds deep handlers, $\SCalc$ that adds shallow
|
||||
handlers, and $\HPCalc$ that adds parameterised handlers. The chapter
|
||||
also contains a running case study that demonstrates effect handler
|
||||
oriented programming in practice by implementing a small operating
|
||||
system dubbed \OSname{} based on \citeauthor{RitchieT74}'s original
|
||||
\UNIX{}.
|
||||
\end{itemize}
|
||||
|
||||
\paragraph{Implementation}
|
||||
Chapter~\ref{ch:cps} develops a higher-order continuation passing
|
||||
\begin{itemize}
|
||||
\item Chapter~\ref{ch:cps} develops a higher-order continuation passing
|
||||
style translation for effect handlers through a series of step-wise
|
||||
refinements of an initial standard continuation passing style
|
||||
translation for $\BCalc$. Each refinement slightly modifies the notion
|
||||
@@ -2047,18 +2082,20 @@ ultimately leads to the key invention of generalised continuation,
|
||||
which is used to give a continuation passing style semantics to deep,
|
||||
shallow, and parameterised handlers.
|
||||
|
||||
Chapter~\ref{ch:abstract-machine} demonstrates an application of
|
||||
\item Chapter~\ref{ch:abstract-machine} demonstrates an application of
|
||||
generalised continuations to abstract machine as we plug generalised
|
||||
continuations into \citeauthor{FelleisenF86}'s CEK machine to obtain
|
||||
an adequate abstract runtime with simultaneous support for deep,
|
||||
shallow, and parameterised handlers.
|
||||
\end{itemize}
|
||||
|
||||
\paragraph{Expressiveness}
|
||||
Chapter~\ref{ch:deep-vs-shallow} shows that deep, shallow, and
|
||||
\begin{itemize}
|
||||
\item Chapter~\ref{ch:deep-vs-shallow} shows that deep, shallow, and
|
||||
parameterised notions of handlers can simulate one another up to
|
||||
specific notions of administrative reduction.
|
||||
|
||||
Chapter~\ref{ch:handlers-efficiency} studies the fundamental efficiency of effect
|
||||
\item Chapter~\ref{ch:handlers-efficiency} studies the fundamental efficiency of effect
|
||||
handlers. In this chapter, we show that effect handlers enable an
|
||||
asymptotic improvement in runtime complexity for a certain class of
|
||||
functions. Specifically, we consider the \emph{generic count} problem
|
||||
@@ -2068,9 +2105,12 @@ of $\BCalc$) and its extension with effect handlers $\HPCF$.
|
||||
We show that $\HPCF$ admits an asymptotically more efficient
|
||||
implementation of generic count than any $\BPCF$ implementation.
|
||||
%
|
||||
\end{itemize}
|
||||
|
||||
\paragraph{Conclusions}
|
||||
Chapter~\ref{ch:conclusions} concludes and discusses future work.
|
||||
\begin{itemize}
|
||||
\item Chapter~\ref{ch:conclusions} concludes and discusses future work.
|
||||
\end{itemize}
|
||||
|
||||
|
||||
\part{Background}
|
||||
@@ -15114,8 +15154,9 @@ $N'$ such that $N' \approxa \sdtrans{N}$ and $M' \reducesto^+ N'$.
|
||||
% By case analysis on $\reducesto$ and induction on $\approxa$ using
|
||||
% Lemma~\ref{lem:sdtrans-subst} and Lemma~\ref{lem:sdtrans-admin}.
|
||||
%
|
||||
By induction on $M' \approxa \sdtrans{M}$ and side induction on
|
||||
$M \reducesto N$ using Lemma~\ref{lem:sdtrans-subst} and Lemma~\ref{lem:sdtrans-admin}.
|
||||
By induction on $M' \approxa \sdtrans{M}$ and case analysis on
|
||||
$M \reducesto N$ using Lemma~\ref{lem:sdtrans-subst} and
|
||||
Lemma~\ref{lem:sdtrans-admin}.
|
||||
%
|
||||
The interesting case is reflexivity of $\approxa$ where
|
||||
$M \reducesto N$ is an application of $\semlab{Op^\dagger}$, which
|
||||
|
||||
Reference in New Issue
Block a user