mirror of
https://github.com/dhil/phd-dissertation
synced 2026-03-13 02:58:26 +00:00
Transparent state-passing
This commit is contained in:
56
thesis.tex
56
thesis.tex
@@ -430,7 +430,9 @@ The evolution of effectful programming has gone through several
|
|||||||
characteristic time periods. In this section I will provide a brief
|
characteristic time periods. In this section I will provide a brief
|
||||||
programming perspective on how effectful programming has evolved as
|
programming perspective on how effectful programming has evolved as
|
||||||
well as providing an informal introduction to the core concepts
|
well as providing an informal introduction to the core concepts
|
||||||
concerned with each time period.
|
concerned with each time period. We will look at the evolution of
|
||||||
|
effectful programming through the lens of a singular effect, namely,
|
||||||
|
global mutable state.
|
||||||
|
|
||||||
\subsection{Early days of direct-style}
|
\subsection{Early days of direct-style}
|
||||||
|
|
||||||
@@ -498,6 +500,29 @@ computation returns the boolean value paired with the final value of
|
|||||||
the state cell.
|
the state cell.
|
||||||
|
|
||||||
\subsubsection{Transparent state-passing purely functionally}
|
\subsubsection{Transparent state-passing purely functionally}
|
||||||
|
It is possible to implement stateful behaviour even in a language
|
||||||
|
without any computational effects, e.g. simply typed
|
||||||
|
$\lambda$-calculus, by following a particular design pattern known as
|
||||||
|
\emph{state-passing}. The principal idea is to parameterise stateful
|
||||||
|
functions by the current state and make them return whatever result
|
||||||
|
they compute along with the updated state value. More precisely, in
|
||||||
|
order to endow some $n$-ary function with argument types $A_i$ and
|
||||||
|
return type $R$ with state of type $S$, we transform the function
|
||||||
|
signature as follows.
|
||||||
|
%
|
||||||
|
\[
|
||||||
|
\val{A_1 \to \cdots \to A_n \to R}_S
|
||||||
|
\defas A_1 \to \cdots \to A_n \to S \to R \times S
|
||||||
|
\]
|
||||||
|
%
|
||||||
|
By convention we always insert the state parameter at the tail end of
|
||||||
|
the parameter list. We may read the suffix $S \to R \times S$ as a
|
||||||
|
sort of effect annotation indicating that a particular function
|
||||||
|
utilises state. The downside of state-passing is that it is a global
|
||||||
|
technique which requires us to rewrite the signatures (and their
|
||||||
|
implementations) of all functions that makes use of state.
|
||||||
|
|
||||||
|
We can reimplement the $\incrEven$ in state-passing style as follows.
|
||||||
%
|
%
|
||||||
\[
|
\[
|
||||||
\bl
|
\bl
|
||||||
@@ -506,17 +531,21 @@ the state cell.
|
|||||||
\el
|
\el
|
||||||
\]
|
\]
|
||||||
%
|
%
|
||||||
State-passing is a global phenomenon that requires us to rewrite the
|
State initialisation is simply function application.
|
||||||
signatures (and their implementations) of all functions that makes use
|
|
||||||
of state, i.e. in order to endow an $n$-ary function that returns some
|
|
||||||
value of type $R$ with state $S$ we have to transform its type as
|
|
||||||
follows.
|
|
||||||
%
|
%
|
||||||
\[
|
\[
|
||||||
\val{A_1 \to \cdots \to A_n \to R}_S
|
\incrEven~\Unit~4 \reducesto^+ \Record{\True;5} : \Bool \times \Int
|
||||||
= A_0 \to \cdots \to A_n \to S \to R \times S
|
|
||||||
\]
|
\]
|
||||||
%
|
%
|
||||||
|
Programming in state-passing style is laborious and no fun as it is
|
||||||
|
anti-modular, because effect-free higher-order functions to work with
|
||||||
|
stateful functions they too must be transformed or at the very least
|
||||||
|
be duplicated to be compatible with stateful function arguments.
|
||||||
|
%
|
||||||
|
Nevertheless, state-passing is an important technique as it is the
|
||||||
|
secret sauce that enables us to simulate mutable state with other
|
||||||
|
programming techniques.
|
||||||
|
|
||||||
\subsubsection{Opaque state-passing with delimited control}
|
\subsubsection{Opaque state-passing with delimited control}
|
||||||
%
|
%
|
||||||
Delimited control appears during the late 80s in different
|
Delimited control appears during the late 80s in different
|
||||||
@@ -699,16 +728,17 @@ Haskell~\cite{JonesABBBFHHHHJJLMPRRW99}.
|
|||||||
\end{reductions}
|
\end{reductions}
|
||||||
\end{definition}
|
\end{definition}
|
||||||
%
|
%
|
||||||
The monad laws ensure that monads have some algebraic structure, which
|
\dhil{Remark that the monad type $T~A$ may be read as a tainted value}
|
||||||
programmers can use when reasoning about their monadic programs, and
|
|
||||||
optimising compilers may take advantage of the structure to emit more
|
|
||||||
efficient code for monadic programs.
|
|
||||||
|
|
||||||
The monad interface may be instantiated in different ways to realise
|
The monad interface may be instantiated in different ways to realise
|
||||||
different computational effects. In the following subsections we will
|
different computational effects. In the following subsections we will
|
||||||
see three different instantiations with which we will implement global
|
see three different instantiations with which we will implement global
|
||||||
mutable state.
|
mutable state.
|
||||||
|
|
||||||
|
The monad laws ensure that monads have some algebraic structure, which
|
||||||
|
programmers can use when reasoning about their monadic programs, and
|
||||||
|
optimising compilers may take advantage of the structure to emit more
|
||||||
|
efficient code for monadic programs.
|
||||||
|
|
||||||
The success of monads as a programming idiom is difficult to
|
The success of monads as a programming idiom is difficult to
|
||||||
understate as monads have given rise to several popular
|
understate as monads have given rise to several popular
|
||||||
control-oriented programming abstractions including the asynchronous
|
control-oriented programming abstractions including the asynchronous
|
||||||
|
|||||||
Reference in New Issue
Block a user