process many comments
[phd-thesis.git] / top / lang.tex
index 2baed8b..a248aa5 100644 (file)
 
 \input{subfilepreamble}
 
+\setcounter{chapter}{4}
+
 \begin{document}
 \input{subfileprefix}
-
-\chapter{The \texorpdfstring{\gls{MTASK}}{mTask} \texorpdfstring{\glsxtrshort{DSL}}{DSL}}%
+\chapter{The mTask language}%
 \label{chp:mtask_dsl}
 \begin{chapterabstract}
-This chapter introduces the \gls{MTASK} language more technically by:
+       This chapter introduces the \gls{TOP} language \gls{MTASK} by:
        \begin{itemize}
-               \item introducing the setup of the \gls{EDSL};
-               \item and showing the language interface and examples for:
-                       \begin{itemize}
-                               \item data types
-                               \item expression
-                               \item task and their combinators.
-                       \end{itemize}
+               \item introducing class-based shallow embedding and the setup of the \gls{MTASK} language;
+               \item describing briefly the various interpretations;
+               \item demonstrating how the type system is leveraged to enforce all constraints;
+               \item showing the language interface for expressions, datatypes, and functions;
+               \item and explaining the tasks, task combinators, and \glspl{SDS}.
        \end{itemize}
 \end{chapterabstract}
 
-The \gls{MTASK} system is a complete \gls{TOP} programming environment for programming microcontrollers, i.e.\ it contains a \gls{TOP} language and a \gls{TOP} engine.
-It is implemented as an \gls{EDSL} in \gls{CLEAN} using class-based---or tagless-final---embedding (see \cref{sec:tagless-final_embedding}).
-Due to the nature of the embedding technique, it is possible to have multiple interpretations for programs written in the \gls{MTASK} language.
-The following interpretations are available for \gls{MTASK}.
+Regular \gls{FP} and \gls{TOP} languages do not run on resource-constrained edge devices.
+A \gls{DSL} is therefore used as the basis of the \gls{MTASK} system, a complete \gls{TOP} programming environment for programming microcontrollers.
+It is implemented as an \gls{EDSL} in \gls{CLEAN} using class-based---or tagless-final---embedding.
+This means that the language interface, i.e.\ the language constructs, are a collection of type classes.
+Interpretations of this interface are data types implementing these classes.
+Due to the nature of this embedding technique, it is possible to have multiple interpretations for programs written in the \gls{MTASK} language.
+Furthermore, this particular type of embedding has the property that it is extensible both in language constructs and in interpretations.
+Adding a language construct is as simple as adding a type class.
+Adding an interpretation is done by creating a new data type and providing implementations for the various type classes.
+
+\todo[inline]{Is dit niet de plek om uit te leggen welke restricties we aan mTask opleggen om het op een edge device te kunnen draaien?
+       1 onderscheid tussen mTask en de rest van het programma
+       2 mTask uit kunnen voeren zonder heap gebruik anders dan de task expressie. Dus: 
+       a geen recursieve data types
+       b geen hogere orde functies
+       c strict evaluation
+       d functies en objecten alleen op topniveau
+Nu lijkt het af en toe dat mTask onnodig primitief is, terwijl we het ook algemener hadden kunnen doen.}
+
+\section{Class-based shallow embedding}
+Let us illustrate this technique by taking the very simple language of literal values.
+This language interface can be described using a single type constructor class with a single function \cleaninline{lit}.
+This function is for lifting values, when it has a \cleaninline{toString} instance, from the host language to our new \gls{DSL}.
+The type variable \cleaninline{v} of the type class represents the view on the language, the interpretation.
+
+\begin{lstClean}
+class literals v where
+       lit :: a -> v a | toString a
+\end{lstClean}
 
-\begin{description}
-       \item[Pretty printer]
+Providing an evaluator is straightforward as can be seen in the following listing.
+The evaluator is just a box holding a value of the computation, but it can also be something more complex such as a monadic computation.
 
-               This interpretation converts the expression to a string representation.
-       \item[Simulator]
+\begin{lstClean}
+:: Eval a = Eval a
 
-               The simulator converts the expression to a ready-for-work \gls{ITASK} simulation in which the user can inspect and control the simulated peripherals and see the internal state of the tasks.
-       \item[Byte code compiler]
+runEval :: (Eval a) -> a
+runEval (Eval a) = a
 
-               The compiler compiles the \gls{MTASK} program at runtime to a specialised byte code.
-               Using a handful of integration functions and tasks, \gls{MTASK} tasks can be executed on microcontrollers and integrated in \gls{ITASK} as if they were regular \gls{ITASK} tasks.
-               Furthermore, with special language constructs, \glspl{SDS} can be shared between \gls{MTASK} and \gls{ITASK} programs.
-\end{description}
+instance literals Eval where
+       lit a = Eval a
+\end{lstClean}
+
+Extending the language with a printer is done by defining a new data type and providing instances for the type constructor classes.
+The printer shown below only stores a printed representation and hence the type variable is just a phantom type:
+
+\begin{lstClean}
+:: Printer a = Printer String
+
+runPrinter :: (Printer a) -> String
+runPrinter (Printer a) = a
+
+instance literals Printer where
+       lit a = Printer (toString a)
+\end{lstClean}
 
-When using the compiler interpretation in conjunction with the \gls{ITASK} integration, \gls{MTASK} is a heterogeneous \gls{DSL}.
-I.e.\ some components---e.g.\ the \gls{RTS} on the microcontroller---is largely unaware of the other components in the system, and it is executed on a completely different architecture.
-The \gls{MTASK} language is an enriched simply-typed $\lambda$-calculus with support for some basic types, arithmetic operations, and function definition; and a task language (see \cref{sec:top}).
+Adding language constructs happens by defining new type classes and giving implementations for the interpretations.
+The following listing adds an addition construct to the language and shows the implementations for the evaluator and printer.
+
+\begin{lstClean}
+class addition v where
+       add :: v a -> v a -> v a | + a
+
+instance addition Eval where
+       add (Eval l) (Eval r) = Eval (l + r)
+
+instance addition Printer where
+       add (Printer l) (Printer r) = Printer ("(" +++ l +++ "+" +++ r +++ ")")
+\end{lstClean}
+
+Terms in our toy language can be overloaded in their interpretation, they are just an interface.
+For example, $1+5$ is written as \cleaninline{add (lit 1) (lit 5)} and has the type \cleaninline{v Int \| literals, addition v}.
+However, due to the way let-polymorphism is implemented in most functional languages, it is not always straightforward to use multiple interpretations in one function.
+Creating such a function, e.g.\ one that both prints and evaluates an expression, requires rank-2 polymorphism (see \cref{lst:rank2_mtask}).
 
 \section{Types}
-To leverage the type checker of the host language, types in the \gls{MTASK} language are expressed as types in the host language, to make the language type safe.
-However, not all types in the host language are suitable for microcontrollers that may only have \qty{2}{\kibi\byte} of \gls{RAM} so class constraints are therefore added to the \gls{DSL} functions.
-The most used class constraint is the \cleaninline{type} class collection containing functions for serialization, printing, \gls{ITASK} constraints, \etc.
-Many of these functions can be derived using generic programming.
-An even stronger restriction on types is defined for types that have a stack representation.
+The \gls{MTASK} language is a tagless-final \gls{EDSL} as well.
+As it is shallowly embedded, the types of the terms in the language can be constrained by type classes.
+Types in the \gls{MTASK} language are expressed as types in the host language, to make the language type safe.
+However, not all types in the host language are suitable for microcontrollers that may only have \qty{2}{\kibi\byte} of \gls{RAM}, so class constraints are added to the \gls{DSL} functions.
+\Cref{tbl:mtask-c-datatypes} shows the mapping from \gls{CLEAN} types to \ccpp{} types.
+The most used class constraint is the \cleaninline{type} class collection containing functions for serialisation, printing, \gls{ITASK} constraints, \etc\ \citep[\citesection{6.9}]{plasmeijer_clean_2021}.
+Most of these functions are automatically derivable using generic programming but can be specialised when needed.
+An even stronger restriction is defined for types that have a stack representation.
 This \cleaninline{basicType} class has instances for many \gls{CLEAN} basic types such as \cleaninline{Int}, \cleaninline{Real} and \cleaninline{Bool}.
-The class constraints for values in \gls{MTASK} are omnipresent in all functions and therefore often omitted throughout throughout the chapters for brevity and clarity.
+These class constraints for values in \gls{MTASK} are omnipresent in all functions and therefore usually omitted for brevity and clarity.
 
 \begin{table}[ht]
        \centering
-       \caption{Mapping from \gls{CLEAN}/\gls{MTASK} data types to \gls{CPP} datatypes.}%
+       \caption{Translation from \cmtask{} data types to \ccpp{} datatypes.}%
        \label{tbl:mtask-c-datatypes}
        \begin{tabular}{lll}
                \toprule
-               \gls{CLEAN}/\gls{MTASK} & \gls{CPP} type & \textnumero{}bits\\
+               \cmtask{}                        & \ccpp{}           & \textnumero{}bits\\
                \midrule
-               \cleaninline{Bool}             & \cinline{bool}    & 16\\
-               \cleaninline{Char}             & \cinline{char}    & 16\\
-               \cleaninline{Int}              & \cinline{int16_t} & 16\\
-               \cleaninline{:: Long}          & \cinline{int32_t} & 32\\
-               \cleaninline{Real}             & \cinline{float}   & 32\\
+               \cleaninline{Bool}               & \cinline{bool}    & 16\\
+               \cleaninline{Char}               & \cinline{char}    & 16\\
+               \cleaninline{Int}                & \cinline{int16_t}\footnotemark{} & 16\\
+               \cleaninline{Real}               & \cinline{float}   & 32\\
+               \cleaninline{:: Long}            & \cinline{int32_t} & 32\\
                \cleaninline{:: T = A \| B \| C} & \cinline{enum}    & 16\\
                \bottomrule
        \end{tabular}
 \end{table}
 
-\Cref{lst:constraints} contains the definitions for the auxiliary types and type constraints (such as \cleaninline{type} an \cleaninline{basicType}) that are used to construct \gls{MTASK} expressions.
-The \gls{MTASK} language interface consists of a core collection of type classes bundled in the type class \cleaninline{class mtask}.
-Every interpretation implements the type classes in the \cleaninline{mtask} class
-There are also \gls{MTASK} extensions that not every interpretation implements such as peripherals and \gls{ITASK} integration.
+\footnotetext{In \gls{ARDUINO} \ccpp{} this usually equals a \cinline{long}.}
+\Cref{lst:constraints} contains the definitions for the auxiliary types and type constraints (such as \cleaninline{type} and \cleaninline{basicType}) that are used to construct \gls{MTASK} expressions.
+
 \begin{lstClean}[caption={Classes and class collections for the \gls{MTASK} language.},label={lst:constraints}]
-class type t | iTask, ... ,fromByteCode, toByteCode t
+class type t | iTask, ... , fromByteCode, toByteCode t
 class basicType t | type t where ...
+\end{lstClean}
 
-class mtask v | expr, ..., int, real, long v
+The \gls{MTASK} language interface consists of a core collection of type classes bundled in the type class \cleaninline{class mtask} (see \cref{lst:collection}).
+Every interpretation of \gls{MTASK} terms implements the type classes in the \cleaninline{mtask} class collection.
+%Optional \gls{MTASK} constructs such as peripherals or lowered \gls{ITASK} \glspl{SDS} are not included in this class collection because not all devices or interpretations support this.
 
+\begin{lstClean}[caption={Class collection for the \gls{MTASK} language.},label={lst:collection}]
+class mtask v | expr, ..., int, real, long v
 \end{lstClean}
 
-Sensors, \glspl{SDS}, functions, \etc{} may only be defined at the top level.
-The \cleaninline{Main} type is used that is used to distinguish the top level from the main expression.
-Some top level definitions, such as functions, are defined using \gls{HOAS}.
-To make their syntax friendlier, the \cleaninline{In} type---an infix tuple---is used to combine these top level definitions as can be seen in \cleaninline{someTask} (\cref{lst:mtask_types}).
+Peripheral, \gls{SDS}, and function definitions are always defined at the top level of \gls{MTASK} programs.
+This is enforced by the \cleaninline{Main} type.
+Most top level definitions are defined using \gls{HOAS}.
+To make their syntax friendlier, the \cleaninline{In} type---an infix tuple---is used to combine these top level definitions.
+To illustrate the structure of a \gls{MTASK} programs, \cref{lst:mtask_types} shows a skeleton of a program.
 
-\begin{lstClean}[caption={Example task and auxiliary types in the \gls{MTASK} language.},label={lst:mtask_types}]
+% VimTeX: SynIgnore on
+\begin{lstClean}[caption={Auxiliary types and example task in the \gls{MTASK} language.},label={lst:mtask_types}]
+// From the mTask library
 :: Main a = { main :: a }
 :: In a b = (In) infix 0 a b
 
-someTask :: MTask v Int | mtask v & liftsds v & sensor1 v & ...
+someTask :: MTask v Int | mtask v & lowerSds v & sensor1 v & ...
 someTask =
        sensor1 config1 \sns1->
        sensor2 config2 \sns2->
-          sds \s1=initial
-       In liftsds \s2=someiTaskSDS
-       In fun \fun1= ( ... )
-       In fun \fun2= ( ... )
+          sds      \s1  = initialValue
+       In lowerSds \s2  = someiTaskSDS
+       In fun      \fun1= ( \(a0, a1)->... )
+       In fun      \fun2= ( \a->... )
        In { main = mainexpr }
 \end{lstClean}
+% VimTeX: SynIgnore off
 
-\section{Expressions}\label{sec:expressions}
-\Cref{lst:expressions} shows the \cleaninline{expr} class containing the functionality to lift values from the host language to the \gls{MTASK} language (\cleaninline{lit}); perform number and boolean arithmetics; do comparisons; and conditional execution.
-For every common boolean and arithmetic operator in the host language, an \gls{MTASK} variant is present, suffixed by a period to not clash with \gls{CLEAN}'s builtin operators.
+Expressions in the \gls{MTASK} language are usually overloaded in their interpretation (\cleaninline{v}).
+In \gls{CLEAN}, all free variables in a type are implicitly universally quantified.
+In order to use the \gls{MTASK} expressions with multiple interpretations, rank-2 polymorphism is required \citep{odersky_putting_1996}.
+\Cref{lst:rank2_mtask} shows an example of a function that simulates an \gls{MTASK} expression while showing the pretty printed representation in parallel.
+Providing a type for the \cleaninline{simulateAndPrint} function is mandatory as the compiler cannot infer the type of rank-2 polymorphic functions\citep[\citesection{3.7.4}]{plasmeijer_clean_2021}.
+
+\begin{lstClean}[label={lst:rank2_mtask},caption={Rank-2 polymorphism to allow multiple interpretations.}]
+simulateAndPrint :: (A.v: Main (MTask v a) | mtask v) -> Task a | type a
+simulateAndPrint mt =
+           simulate mt
+       -|| Hint "Current task:" @>> viewInformation [] (showMain mt)
+\end{lstClean}
 
-\begin{lstClean}[caption={The \gls{MTASK} class for expressions},label={lst:expressions}]
+\section{Expressions}\label{sec:expressions}
+This section shows all \gls{MTASK} language constructs for expressions.
+\Cref{lst:expressions} shows the \cleaninline{expr} class containing the functionality to:
+lift values from the host language to the \gls{MTASK} language (\cleaninline{lit});
+perform numeric and boolean arithmetics;
+do comparisons;
+and perform conditional execution.
+For every common boolean and arithmetic operator in the host language, an \gls{MTASK} variant is present.
+The operators are suffixed by a period to not clash with the built-in operators in \gls{CLEAN}.
+
+\begin{lstClean}[caption={The \gls{MTASK} class for expressions.},label={lst:expressions}]
 class expr v where
        lit :: t -> v t | type t
        (+.) infixl 6 :: (v t) (v t) -> v t | basicType, +, zero t
@@ -119,7 +200,9 @@ class expr v where
        If :: (v Bool) (v t) (v t) -> v t | type t
 \end{lstClean}
 
-Conversion to-and-fro data types is available through the overloaded functions \cleaninline{int}, \cleaninline{long} and \cleaninline{real} that will convert the argument to the respective type similar to casting in \gls{C}.
+Conversion to and fro data types is available through the overloaded functions \cleaninline{int}, \cleaninline{long} and \cleaninline{real}.
+These functions convert the argument to the respective type similar to casting in \gls{C}.
+For most interpretations, there are instances of these classes for all numeric types.
 
 \begin{lstClean}[caption={Type conversion functions in \gls{MTASK}.}]
 class int  v a :: (v a) -> v Int
@@ -128,48 +211,48 @@ class long v a :: (v a) -> v Long
 \end{lstClean}
 
 Values from the host language must be explicitly lifted to the \gls{MTASK} language using the \cleaninline{lit} function.
-For convenience, there are many lower-cased macro definitions for often used constants such as \cleaninline{true :== lit True}, \cleaninline{false :== lit False}, \etc.
+For convenience, there are many lower-cased macro definitions for often-used constants such as \cleaninline{true :== lit True}, \cleaninline{false :== lit False}.
 
-\Cref{lst:example_exprs} shows some examples of these expressions.
+\Cref{lst:example_exprs} shows some examples of expressions in the \gls{MTASK} language.
 Since they are only expressions, there is no need for a \cleaninline{Main}.
-\cleaninline{e0} defines the literal $42$, \cleaninline{e1} calculates the literal $42.0$ using real numbers.
-\cleaninline{e2} compares \cleaninline{e0} and \cleaninline{e1} as integers and if they are equal it returns the \cleaninline{e2}$/2$ and \cleaninline{e0} otherwise.
+\cleaninline{e0} defines the literal \num{42}, \cleaninline{e1} calculates the literal \num{42.0} using real numbers and uses a type conversion.
+\cleaninline{e2} compares \cleaninline{e0} and \cleaninline{e1} as integers and if they are equal it returns $\frac{\text{\cleaninline{e2}}}{2}$ and \cleaninline{e0} otherwise.
 
 \begin{lstClean}[label={lst:example_exprs},caption={Example \gls{MTASK} expressions.}]
 e0 :: v Int | expr v
 e0 = lit 42
 
 e1 :: v Real | expr v
-e1 = lit 38.0 + real (lit 4)
+e1 = lit 38.0 +. real (lit 4)
 
 e2 :: v Int | expr v
-e2 = if' (e0 ==. int e1)
+e2 = If (e0 ==. int e1)
        (int e1 /. lit 2) e0
 \end{lstClean}
 
-\Gls{MTASK} is shallowly embedded in \gls{CLEAN} and the terms are constructed at runtime.
-This means that \gls{MTASK} programs can also be tailor-made at runtime or constructed using \gls{CLEAN} functions maximising the linguistic reuse \citep{krishnamurthi_linguistic_2001}
-\cleaninline{approxEqual} in \cref{lst:example_macro} performs an approximate equality---albeit not taking into account all floating point pecularities---.
-When calling \cleaninline{approxEqual} in an \gls{MTASK} function, the resulting code is inlined.
-
-\begin{lstClean}[label={lst:example_macro},caption={Example linguistic reuse in the \gls{MTASK} language.}]
-approxEqual :: (v Real) (v Real) (v Real) -> v Real | expr v
-approxEqual x y eps = if' (x ==. y) true
-       ( if' (x >. y)
-               (y -. x < eps)
-               (x -. y < eps)
-       )
+The \gls{MTASK} language is shallowly embedded in \gls{CLEAN} and the terms are constructed and hence compiled at run time.
+This means that \gls{MTASK} programs can also be tailor-made at run time using \gls{CLEAN} functions, maximising the linguistic reuse \citep{krishnamurthi_linguistic_2001}.
+The \cleaninline{approxEqual} function in \cref{lst:example_macro} is an example of this.
+It performs a simple approximate equality---admittedly not taking into account all floating point peculiarities.
+When calling \cleaninline{approxEqual} in an \gls{MTASK} expression, the resulting code is inlined.
+
+\begin{lstClean}[label={lst:example_macro},caption={Approximate equality as an example of linguistic reuse in \gls{MTASK}.}]
+approxEqual :: (v Real) (v Real) (v Real) -> v Bool | expr v
+approxEqual x y eps = x ==. y |.  If (x >. y)
+       (x -. y <. eps)
+       (y -. x <. eps)
 \end{lstClean}
 
 \subsection{Data types}
-Most of \gls{CLEAN}'s basic types have been mapped on \gls{MTASK} types.
-However, it can be useful to have access to compound types as well.
-All types in \gls{MTASK} must have a fixed size representation on the stack so sum types are not (yet) supported.
-While it is possible to lift types using the \cleaninline{lit} function, you cannot do anything with the types besides passing them around but they are being produced by some parallel task combinators (see \cref{sssec:combinators_parallel}).
-To be able to use types as first class citizens, constructors and field selectors are required (see \cref{chp:first-class_datatypes}).
-\Cref{lst:tuple_exprs} shows the scaffolding for supporting tuples in \gls{MTASK}.
-Besides the constructors and field selectors, there is also a helper function available that transforms a function from a tuple of \gls{MTASK} expressions to an \gls{MTASK} expression of a tuple.
-Examples for using tuple can be found in \cref{sec:mtask_functions}.
+Most of the fixed-size basic types from \gls{CLEAN} are mapped on \gls{MTASK} types (see \cref{tbl:mtask-c-datatypes}).
+However, it is useful to have access to compound types as well.
+All types in \gls{MTASK} have a fixed-size representation on the stack, so sum types are not (yet) supported.
+It is possible to lift any types, e.g.\ tuples, using the \cleaninline{lit} function as long as they have instances for the required type classes.
+However, you cannot do anything with values of the types besides passing them around.
+To be able to use types as first-class citizens, constructors, and field selectors or deconstructors are required (see \cref{chp:first-class_datatypes}).
+\Cref{lst:tuple_exprs} shows the scaffolding required for supporting tuples in \gls{MTASK}.
+Besides the constructors and field selectors, there is also a helper function available that transforms a function from a tuple of \gls{MTASK} expressions to an \gls{MTASK} expression of a tuple, a deconstructor.
+Examples of \gls{MTASK} programs using tuples are seen later in \cref{sec:mtask_functions}.
 
 \begin{lstClean}[label={lst:tuple_exprs},caption={Tuple constructor and field selectors in \gls{MTASK}.}]
 class tupl v where
@@ -177,49 +260,55 @@ class tupl v where
        first :: (v (a, b)) -> v a | type a & type b
        second :: (v (a, b)) -> v b | type a & type b
 
+       tupopen :: ((v a, v b) -> v c) -> ((v (a, b)) -> v c)
        tupopen f :== \v->f (first v, second v)
 \end{lstClean}
 
 \subsection{Functions}\label{sec:mtask_functions}
-Adding functions to the language is achieved by type class to the \gls{DSL}.
+Adding functions to the language is achieved by one type class to the \gls{DSL}.
 By using \gls{HOAS}, both the function definition and the calls to the function can be controlled by the \gls{DSL} \citep{pfenning_higher-order_1988,chlipala_parametric_2008}.
-The \gls{MTASK} only allows first-order functions and does not allow partial function application.
-This is restricted by using a multi-parameter type class where the first parameter represents the arguments and the second parameter the view.
-By providing a single instance per function arity instead of providing one instance for all functions and using tuples for the arguments this constraint can be enforced.
-Also, \gls{MTASK} only supports top-level functions which is enforced by the \cleaninline{Main} box.
-The definition of the type class and the instances for an example interpretation (\cleaninline{:: Inter}) are as follows:
+The \gls{MTASK} language only allows first-order functions and no partial function application.
+To restrict this, a multi-parameter type class is used instead of a type class with one type variable.
+The first parameter represents the shape of the arguments, the second parameter the interpretation.
+An instance is provided for each function arity instead of providing an instance for all possible arities to enforce that all functions are first order.
+By using argument tuples to represent the arity of the function, partial function applications are eradicated.
+The definition of the type class and some instances for the pretty printer are as follows:
 
 \begin{lstClean}[caption={Functions in \gls{MTASK}.}]
 class fun a v :: ((a -> v s) -> In (a -> v s) (Main (MTask v u)))
        -> Main (MTask v u)
 
-instance fun () Inter where ...
-instance fun (Inter a) Inter | type a where ...
-instance fun (Inter a, Inter b) Inter | type a, type b where ...
-instance fun (Inter a, Inter b, Inter c) Inter | type a, ... where ...
+instance fun () Show where ...
+instance fun (Show a) Show | type a where ...
+instance fun (Show a, Show b) Show | type a, type b where ...
+instance fun (Show a, Show b, Show c) Show | type a, ... where ...
 ...
 \end{lstClean}
 
-Deriving how to define and use functions from the type is quite the challenge even though the resulting syntax is made easier using the infix type \cleaninline{In}.
-\Cref{lst:function_examples} show the factorial function, a tail-call optimised factorial function and a function with zero arguments to demonstrate the syntax.
-Splitting out the function definition for each single arity means that that for every function arity and combination of arguments, a separate class constraint must be created.
+Deriving how to define and use functions from the type is quite a challenge even though the resulting syntax is made easier using the infix type \cleaninline{In}.
+\Cref{lst:function_examples} show some examples of functions to illustrate the syntax.
+Splitting out the function definition for each single arity means that for every function arity and combination of arguments, a separate class constraint must be created.
 Many of the often used functions are already bundled in the \cleaninline{mtask} class constraint collection.
-\cleaninline{factorialtail} shows a manually added class constraint.
-Definiting zero arity functions is shown in the \cleaninline{zeroarity} expression.
+The \cleaninline{factorial} functions shows a recursive version of the factorial function.
+The \cleaninline{factorialtail} function is a tail-call optimised version of the factorial function.
+It contains a manually added class constraint.
+\todo[inline]{Uitleggen waarom je dit doet}
+Zero-arity functions are always called with unit as an argument.
+An illustration of this is seen in the \cleaninline{zeroarity} expression.
 Finally, \cleaninline{swapTuple} shows an example of a tuple being swapped.
 
 % VimTeX: SynIgnore on
-\begin{lstClean}[label={lst:function_examples},caption={Function examples in \gls{MTASK}.}]
+\begin{lstClean}[label={lst:function_examples},caption={Examples of various functions in \gls{MTASK}.}]
 factorial :: Main (v Int) | mtask v
 factorial =
-       fun \fac=(\i->if' (i <. lit 1)
+       fun \fac=(\i->If (i <. lit 1)
                (lit 1)
                (i *. fac (i -. lit 1)))
        In {main = fac (lit 5) }
 
 factorialtail :: Main (v Int) | mtask v & fun (v Int, v Int) v
 factorialtail =
-          fun \facacc=(\(acc, i)->if' (i <. lit 1)
+          fun \facacc=(\(acc, i)->If (i <. lit 1)
                        acc
                        (fac (acc *. i, i -. lit 1)))
        In fun \fac=(\i->facacc (lit 1, i))
@@ -239,85 +328,92 @@ swapTuple =
 % VimTeX: SynIgnore off
 
 \section{Tasks and task combinators}\label{sec:top}
-\Gls{MTASK}'s task language can be divided into three categories, namely
-\begin{enumerate*}
-       \item Basic tasks, in most \gls{TOP} systems, the basic tasks are called editors, modelling the interactivity with the user.
-               In \gls{MTASK}, there are no \emph{editors} in that sense but there is interaction with the outside world through microcontroller peripherals such as sensors and actuators.
-       \item Task combinators provide a way of describing the workflow.
+This section describes the task language of \gls{MTASK}.
+\Gls{TOP} languages are programming languages enriched with tasks.
+Tasks represent abstract pieces of work and can be combined using combinators.
+Creating tasks is done by evaluating expressions.
+The result of an evaluated task expression is called a task tree, a run time representation of a task.
+In order to evaluate a task, the resulting task tree is \emph{rewritten}, i.e.\ similar to rewrite systems, they perform a bit of work, step by step.
+With each step, a task value is yielded that is observable by other tasks and can be acted upon.
+
+The implementation in the \gls{MTASK} \gls{RTS} for task execution is shown in \cref{chp:implementation}.
+The following sections show the definitions of the functions for creating tasks.
+They also show the semantics of tasks: their observable value in relation to the work that the task represents.
+The task language of \gls{MTASK} is divided into three categories:
+
+\begin{description}
+       \item [Basic tasks] are the leaves in the task trees.
+               In most \gls{TOP} systems, the basic tasks are called editors, modelling the interactivity with the user.
+               In \gls{MTASK}, there are no editors in that sense.
+               Editors in \gls{MTASK} model the interaction with the outside world through peripherals such as sensors and actuators.
+       \item [Task combinators] provide a way of describing the workflow or collaboration.
                They combine one or more tasks into a compound task.
-       \item \glspl{SDS} in \gls{MTASK} can be seen as references to data that can be shared using many-to-many communication and are only accessible from within the task language to ensure atomicity.
-\end{enumerate*}
+       \item [\Glspl{SDS}] are typed references to shared memory in \gls{MTASK}.
+               The data is available for tasks using many-to-many communication but only from within the task language to ensure atomicity.
+\end{description}
 
-As \gls{MTASK} is integrated with \gls{ITASK}, the same stability distinction is made for task values.
+As \gls{MTASK} is integrated with \gls{ITASK}, a stability distinction is made for task values just as in \gls{ITASK}.
 A task in \gls{MTASK} is denoted by the \gls{DSL} type synonym shown in \cref{lst:task_type}.
+A task is an expression of the type \cleaninline{TaskValue a} in interpretation \cleaninline{v}.
 
 \begin{lstClean}[label={lst:task_type},caption={Task type in \gls{MTASK}.}]
 :: MTask v a :== v (TaskValue a)
+
+// From the iTask library
 :: TaskValue a
        = NoValue
        | Value a Bool
 \end{lstClean}
 
 \subsection{Basic tasks}
-The most rudimentary basic tasks are the \cleaninline{rtrn} and \cleaninline{unstable} tasks.
-They lift the value from the \gls{MTASK} expression language to the task domain either as a stable value or an unstable value.
+The \gls{MTASK} language contains interactive and non-interactive basic tasks.
+As \gls{MTASK} is integrated in \gls{ITASK}, the same notion of stability is applied to the observable task value (see \cref{fig:taskvalue}).
+\todo[inline]{Stability beter uitleggen?}
+The most rudimentary non-interactive basic tasks in the task language of \gls{MTASK} are \cleaninline{rtrn} and \cleaninline{unstable}.
+They lift the value from the \gls{MTASK} expression language to the task domain either as a stable or unstable value.
 There is also a special type of basic task for delaying execution.
-The \cleaninline{delay} task---given a number of milliseconds---yields an unstable value while the time has not passed.
+The \cleaninline{delay} task---parametrised by a number of milliseconds---yields an unstable value while the time has not passed.
 Once the specified time has passed, the time it overshot the planned time is yielded as a stable task value.
 See \cref{sec:repeat} for an example task using \cleaninline{delay}.
 
-\begin{lstClean}[label={lst:basic_tasks},caption={Function examples in \gls{MTASK}.}]
+\begin{lstClean}[label={lst:basic_tasks},caption={Non-interactive basic tasks in \gls{MTASK}.}]
 class rtrn v :: (v t) -> MTask v t
 class unstable v :: (v t) -> MTask v t
 class delay v :: (v n) -> MTask v n | long v n
 \end{lstClean}
 
 \subsubsection{Peripherals}\label{sssec:peripherals}
-For every sensor or actuator, basic tasks are available that allow interaction with the specific peripheral.
-The type classes for these tasks are not included in the \cleaninline{mtask} class collection as not all devices nor all language interpretations have such peripherals connected.
-%\todo{Historically, peripheral support has been added \emph{by need}.}
-
-\Cref{lst:dht,lst:gpio} show the type classes for \glspl{DHT} sensors and \gls{GPIO} access.
-Other peripherals have similar interfaces, they are available in the \cref{sec:aux_peripherals}.
-For the \gls{DHT} sensor there are two basic tasks, \cleaninline{temperature} and \cleaninline{humidity}, that---will given a \cleaninline{DHT} object---produce a task that yields the observed temperature in \unit{\celcius} or relative humidity as a percentage as an unstable value.
-Currently, two different types of \gls{DHT} sensors are supported, the \emph{DHT} family of sensors connect through $1$-wire protocol and the \emph{SHT} family of sensors connected using \gls{I2C} protocol.
-Creating such a \cleaninline{DHT} object is very similar to creating functions in \gls{MTASK} and uses \gls{HOAS} to make it type safe.
-
-\begin{lstClean}[label={lst:dht},caption{The \gls{MTASK} interface for \glspl{DHT} sensors.}]
-:: DHT //abstract
-:: DHTInfo
-       = DHT_DHT Pin DHTtype
-       | DHT_SHT I2CAddr
-:: DHTtype = DHT11 | DHT21 | DHT22
-class dht v where
-       DHT :: DHTInfo ((v DHT) -> Main (v b)) -> Main (v b) | type b
-       temperature :: (v DHT) -> MTask v Real
-       humidity :: (v DHT) -> MTask v Real
-
-measureTemp :: Main (MTask v Real) | mtask v & dht v
-measureTemp = DHT (DHT_SHT (i2c 0x36)) \dht->
-       {main=temperature dht}
-\end{lstClean}
-
-\Gls{GPIO} access is divided into three classes: analog, digital and pin modes.
-For all pins and pin modes an \gls{ADT} is available that enumerates the pins.
-The analog \gls{GPIO} pins of a microcontroller are connected to an \gls{ADC} that translates the voltage to an integer.
-Analog \gls{GPIO} pins can be either read or written to.
-Digital \gls{GPIO} pins only report a high or a low value.
-The type class definition is a bit more complex since analog \gls{GPIO} pins can be used as digital \gls{GPIO} pins as well.
-Therefore, if the \cleaninline{p} type implements the \cleaninline{pin} class---i.e.\ either \cleaninline{APin} or \cleaninline{DPin}---the \cleaninline{dio} class can be used.
+In order for the edge device to interact with the environment, peripherals such as sensors and actuators are employed.
+Some peripherals are available on the microcontroller package, others are connected with wires using protocols such as \gls{I2C}.
+For every supported sensor or actuator, basic tasks are available that allow interaction with the specific peripheral.
+The type classes for these tasks are not included in the \cleaninline{mtask} class collection as not all devices nor all language interpretations support every peripheral connected.
+
+An example of a built-in peripheral is the \gls{GPIO} system.
+This array of digital and analogue pins is controlled through software.
+\Gls{GPIO} access is divided into three classes: analogue \gls{IO}, digital \gls{IO} and pin mode configuration (see \cref{lst:gpio}).
+For all pins and pin modes, an \gls{ADT} is available that enumerates the pins.
+The analogue \gls{GPIO} pins of a microcontroller are connected to an \gls{ADC} that translates the measured voltage to an integer.
+Digital \gls{GPIO} pins of a microcontroller report either a high or a low value.
+Both analogue and digital \gls{GPIO} pins can be read or written to, but it is advised to set the pin mode accordingly.
+The \cleaninline{pin} type class allows functions to be overloaded in either the analogue or digital pins, e.g.\ analogue pins can be considered digital pins as well.
+
+For digital \gls{GPIO} interaction, the \cleaninline{dio} type class is used.
+The first argument of the functions in this class is overloaded, i.e.\ it accepts either an \cleaninline{APin} or a \cleaninline{DPin}.
+Analogue \gls{GPIO} tasks are bundled in the \cleaninline{aio} type class.
 \Gls{GPIO} pins usually operate according to a certain pin mode that states whether the pin acts as an input pin, an input with an internal pull-up resistor or an output pin.
-This setting can be applied using the \cleaninline{pinMode} class by hand or by using the \cleaninline{declarePin} \gls{GPIO} pin constructor.
-Setting the pin mode is a task that immediately finisheds and fields a stable unit value.
-Writing to a pin is also a task that immediately finishes but yields the written value instead.
+This setting can be set using the \cleaninline{pinMode} class by hand or by using the \cleaninline{declarePin} \gls{GPIO} pin constructor to declare it at the top level.
+Setting the pin mode is a task that immediately finishes and yields a stable unit value.
+Writing to a pin is also a task that immediately finishes, but yields the written value.
 Reading a pin is a task that yields an unstable value---i.e.\ the value read from the actual pin.
 
 \begin{lstClean}[label={lst:gpio},caption={The \gls{MTASK} interface for \gls{GPIO} access.}]
 :: APin = A0 | A1 | A2 | A3 | A4 | A5
-:: DPin = D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 | D10 | D11 | D12 | D13
+:: DPin = D0 | D1 | D2 | D3 | D4 | D5 | D6 | D7 | D8 | D9 | D10 | ...
 :: PinMode = PMInput | PMOutput | PMInputPullup
 :: Pin = AnalogPin APin | DigitalPin DPin
+
 class pin p :: p -> Pin
+instance pin APin, DPin
 
 class aio v where
        writeA :: (v APin) (v Int) -> MTask v Int
@@ -332,6 +428,12 @@ class pinMode v where
        declarePin :: p PinMode ((v p) -> Main (v a)) -> Main (v a) | pin p
 \end{lstClean}
 
+\Cref{lst:gpio_examples} shows two examples of \gls{MTASK} tasks using \gls{GPIO} pins.
+\cleaninline{task1} reads analogue \gls{GPIO} pin 3.
+This is a task that never terminates.
+\cleaninline{task2} writes the \cleaninline{true} (\gls{ARDUINO} \arduinoinline{HIGH}) value to digital \gls{GPIO} pin 3.
+This task finishes immediately after writing to the pin.
+
 \begin{lstClean}[label={lst:gpio_examples},caption={\Gls{GPIO} example in \gls{MTASK}.}]
 task1 :: MTask v Int | mtask v
 task1 = declarePin A3 PMInput \a3->{main=readA a3}
@@ -340,22 +442,48 @@ task2 :: MTask v Int | mtask v
 task2 = declarePin D3 PMOutput \d3->{main=writeD d3 true}
 \end{lstClean}
 
+Peripherals are bundled by their functionality in \gls{MTASK}.
+For example, \cref{lst:dht} shows the type classes for all supported \gls{DHT} sensors.
+Currently, two different types of \gls{DHT} sensors are supported, the \emph{DHT} family of sensors connect through the \gls{ONEWIRE} protocol and the \emph{SHT} family of sensors connected using the \gls{I2C} protocol.
+Creating such a \cleaninline{DHT} object is very similar to creating functions in \gls{MTASK} and uses \gls{HOAS} to make it type safe.
+When provided a configuration and a configuration function, the \gls{DHT} object can be brought into scope.
+For the \gls{DHT} sensor there are two basic tasks, \cleaninline{temperature} and \cleaninline{humidity}, that produce a task that yields the observed temperature in \unit{\celcius} or the relative humidity as an unstable value.
+Other peripherals have similar interfaces, they are available in \cref{sec:aux_peripherals}.
+
+\begin{lstClean}[label={lst:dht},caption={The \gls{MTASK} interface for \glspl{DHT} sensors.}]
+:: DHT //abstract
+:: DHTInfo
+       = DHT_DHT Pin DHTtype
+       | DHT_SHT I2CAddr
+:: DHTtype = DHT11 | DHT21 | DHT22
+class dht v where
+       DHT :: DHTInfo ((v DHT) -> Main (v b)) -> Main (v b) | type b
+       temperature :: (v DHT) -> MTask v Real
+       humidity :: (v DHT) -> MTask v Real
+
+measureTemp :: Main (MTask v Real) | mtask, dht v
+measureTemp = DHT (DHT_SHT (i2c 0x36)) \dht->{main=temperature dht}
+\end{lstClean}
+
 \subsection{Task combinators}
-Task combinators are used to combine multiple tasks into one to describe workflows.
+Task combinators are used to combine multiple tasks to describe workflows.
+The \gls{MTASK} language has a set of simpler combinators from which more complicated workflow can be derived.
 There are three main types of task combinators, namely:
-\begin{enumerate*}
-       \item Sequential combinators that execute tasks one after the other, possibly using the result of the left hand side.
-       \item Parallel combinators that execute tasks at the same time combining the result.
-       \item Miscellaneous combinators that change the semantics of a task---e.g.\ repeat it or delay execution.
-\end{enumerate*}
+\begin{itemize}
+       \item sequential combinators that execute tasks one after the other, possibly using the result of the left-hand side;
+       \item parallel combinators that execute tasks at the same time, combining the result;
+       \item miscellaneous combinators that change the semantics of a task---for example a combinator that repeats the child task.
+\end{itemize}
 
 \subsubsection{Sequential}
-Sequential task combination allows the right-hand side task to observe the left-hand side task value.
-All seqential task combinators are expressed in the \cleaninline{expr} class and can be---and are by default---derived from the Swiss army knife step combinator \cleaninline{>>*.}.
+Sequential task combination allows the right-hand side expression to \emph{observe} the left-hand side task value.
+All sequential task combinators are defined in the \cleaninline{step} class and are by default defined in terms of the Swiss Army knife step combinator (\cleaninline{>>*.}, \cref{lst:mtask_sequential}).
 This combinator has a single task on the left-hand side and a list of \emph{task continuations} on the right-hand side.
-The list of task continuations is checked every rewrite step and if one of the predicates matches, the task continues with the result of this combination.
+Every rewrite step, the list of task continuations are tested on the task value.
+If one of the predicates matches, the task continues with the result of these continuations.
+Several shorthand combinators are derived from the step combinator.
 \cleaninline{>>=.} is a shorthand for the bind operation, if the left-hand side is stable, the right-hand side function is called to produce a new task.
-\cleaninline{>>|.} is a shorthand for the sequence operation, if the left-hand side is stable, it continues with the right-hand side task.
+\cleaninline{>>\|.} is a shorthand for the sequence operation, if the left-hand side is stable, it continues with the right-hand side task.
 The \cleaninline{>>~.} and \cleaninline{>>..} combinators are variants of the ones above that ignore the stability and continue on an unstable value as well.
 
 \begin{lstClean}[label={lst:mtask_sequential},caption={Sequential task combinators in \gls{MTASK}.}]
@@ -373,31 +501,33 @@ class step v | expr v where
        | Always                                (MTask v u)
 \end{lstClean}
 
-\todo{more examples step?}
-
 The following listing shows an example of a step in action.
 The \cleaninline{readPinBin} function produces an \gls{MTASK} task that classifies the value of an analogue pin into four bins.
 It also shows that the nature of embedding allows the host language to be used as a macro language.
-Furthermore
 
-\begin{lstClean}[label={lst:mtask_readpinbin},caption={Read an analog pin and bin the value in \gls{MTASK}.}]
+\begin{lstClean}[label={lst:mtask_readpinbin},caption={Read an analogue pin and bin the value in \gls{MTASK}.}]
 readPinBin :: Int -> Main (MTask v Int) | mtask v
 readPinBin lim = declarePin PMInput A2 \a2->
        { main = readA a2 >>*.
                [  IfValue (\x->x <. lim) (\_->rtrn (lit bin))
-               \\ lim <-[64,128,192,256]
+               \\ lim <- [64,128,192,256]
                &  bin <- [0..]]}
 \end{lstClean}
 
 \subsubsection{Parallel}\label{sssec:combinators_parallel}
-The result of a parallel task combination is a compound that actually executes the tasks at the same time.
+The result of a parallel task combination is a compound task that executes both tasks at the same time.
+There are two types of parallel task combinators in the \gls{MTASK} language (see \cref{lst:mtask_parallel}).
+
+\begin{lstClean}[label={lst:mtask_parallel},caption={Parallel task combinators in \gls{MTASK}.}]
+class (.&&.) infixr 4 v :: (MTask v a) (MTask v b) -> MTask v (a, b)
+class (.||.) infixr 3 v :: (MTask v a) (MTask v a) -> MTask v a
+\end{lstClean}
 
-There are two types of parallel task combinators (see \cref{lst:mtask_parallel}).
 The conjunction combinator (\cleaninline{.&&.}) combines the result by putting the values from both sides in a tuple.
 The stability of the task depends on the stability of both children.
 If both children are stable, the result is stable, otherwise the result is unstable.
 The disjunction combinator (\cleaninline{.\|\|.}) combines the results by picking the leftmost, most stable task.
-The semantics are easily described using \gls{CLEAN} functions shown in \cref{lst:semantics_con,lst:semantics_dis}.
+The semantics of both parallel combinators are most easily described using the \gls{CLEAN} functions shown in \cref{lst:semantics_con,lst:semantics_dis}.
 
 \begin{figure}[ht]
        \centering
@@ -405,8 +535,8 @@ The semantics are easily described using \gls{CLEAN} functions shown in \cref{ls
                \begin{lstClean}[caption={Semantics of the\\conjunction combinator.},label={lst:semantics_con}]
 con :: (TaskValue a) (TaskValue b)
        -> TaskValue (a, b)
-con NoValue r       = NoValue
-con l       NoValue = NoValue
+con NoValue r = NoValue
+con l NoValue = NoValue
 con (Value l ls) (Value r rs)
        = Value (l, r) (ls && rs)
 
@@ -416,63 +546,63 @@ con (Value l ls) (Value r rs)
                \begin{lstClean}[caption={Semantics of the\\disjunction combinator.},label={lst:semantics_dis}]
 dis :: (TaskValue a) (TaskValue a)
        -> TaskValue a
-dis NoValue r       = r
-dis l       NoValue = l
+dis NoValue r = r
+dis l NoValue = l
 dis (Value l ls) (Value r rs)
-       | rs        = Value r True
+       | rs && not ls = Value r rs
        | otherwise = Value l ls
                \end{lstClean}
        \end{subfigure}
 \end{figure}
 
-\begin{lstClean}[label={lst:mtask_parallel},caption={Parallel task combinators in \gls{MTASK}.}]
-class (.&&.) infixr 4 v :: (MTask v a) (MTask v b) -> MTask v (a, b)
-class (.||.) infixr 3 v :: (MTask v a) (MTask v a) -> MTask v a
-\end{lstClean}
-
-\Cref{lst:mtask_parallel_example} gives an example of the parallel task combinator.
-This program will read two pins at the same time, returning when one of the pins becomes \arduinoinline{HIGH}.
-If the combinator was the \cleaninline{.&&.} instead, the type would be \cleaninline{MTask v (Bool, Bool)} and the task would only return when both pins have been \arduinoinline{HIGH} but not necessarily at the same time.
+\Cref{lst:mtask_parallel_example} gives an example program that uses the parallel task combinator.
+This task read two pins at the same time, returning when one of the pins becomes high.
+If the combinator was the \cleaninline{.&&.}, the type would be \cleaninline{MTask v (Bool, Bool)} and the task would only return when both pins are high but not necessarily at the same time.
 
 \begin{lstClean}[label={lst:mtask_parallel_example},caption={Parallel task combinator example in \gls{MTASK}.}]
 task :: MTask v Bool
 task =
        declarePin D0 PMInput \d0->
        declarePin D1 PMInput \d1->
-       let monitor pin = readD pin >>*. [IfValue (\x->x) \x->rtrn x]
+       let monitor pin = readD pin >>*. [IfValue id rtrn]
        In {main = monitor d0 .||. monitor d1}
 \end{lstClean}
 
 \subsubsection{Repeat}\label{sec:repeat}
-The \cleaninline{rpeat} combinator executes the child task.
-If a stable value is observed, the task is reinstated.
-The functionality of \cleaninline{rpeat} can also be simulated by using functions and sequential task combinators and even made to be stateful as can be seen in \cref{lst:blinkthreadmtask}.
+In many workflows, tasks are to be executed repeatedly.
+The \cleaninline{rpeat} combinator does this by executing the child task until it becomes stable.
+Once a stable value is observed, the task is reinstated.
+The functionality of \cleaninline{rpeat} can also be simulated by using functions and sequential task combinators and even made to be stateful as can be seen from the blink example from \cref{chp:top4iot}.
 
 \begin{lstClean}[label={lst:mtask_repeat},caption={Repeat task combinators in \gls{MTASK}.}]
 class rpeat v where
        rpeat :: (MTask v a) -> MTask v a
 \end{lstClean}
 
-To demonstrate the combinator, \cref{lst:mtask_repeat_example} show \cleaninline{rpeat} in use.
-This task will mirror the value read from analog \gls{GPIO} pin \cleaninline{A1} to pin \cleaninline{A2} by constantly reading the pin and writing the result.
+\Cref{lst:mtask_repeat_example} shows an example of a task that uses the \cleaninline{rpeat} combinator.
+This resulting task mirrors the value read from analogue \gls{GPIO} pin \cleaninline{A1} to pin \cleaninline{A2} by constantly reading the pin and writing the result.
 
-\begin{lstClean}[label={lst:mtask_repeat_example},caption={Exemplatory repeat task in \gls{MTASK}.}]
+\begin{lstClean}[label={lst:mtask_repeat_example},caption={Repeat task combinator example in \gls{MTASK}.}]
 task :: MTask v Int | mtask v
-task =
-       declarePin A1 PMInput \a1->
-       declarePin A2 PMOutput \a2->
-       {main = rpeat (readA a1 >>~. writeA a2 >>|. delay (lit 1000))}
+task = declarePin A1 PMInput  \a1->
+       declarePin A2 PMOutput \a2->
+       {main = rpeat (readA a1 >>~. writeA a2 >>|. delay (lit 1000))}
 \end{lstClean}
 
-\subsection{\texorpdfstring{\Glsxtrlongpl{SDS}}{Shared data sources}}
+\subsection{Shared data sources}
+For some collaborations it is cumbersome to only communicate data using task values.
+\Glspl{SDS} are a safe abstraction over any data that fill this gap.
+It allows tasks to safely and atomically read, write and update data stores in order to share data with other tasks.
 \Glspl{SDS} in \gls{MTASK} are by default references to shared memory but can also be references to \glspl{SDS} in \gls{ITASK} (see \cref{sec:liftsds}).
-Similar to peripherals (see \cref{sssec:peripherals}), they are constructed at the top level and are accessed through interaction tasks.
+There are no combinators or user-defined \gls{SDS} types in \gls{MTASK} as there are in \gls{ITASK}.
+Similar to peripherals and functions, \glspl{SDS} are defined at the top level with the \cleaninline{sds} function.
+They are accessed through interaction tasks.
 The \cleaninline{getSds} task yields the current value of the \gls{SDS} as an unstable value.
 This behaviour is similar to the \cleaninline{watch} task in \gls{ITASK}.
 Writing a new value to \pgls{SDS} is done using \cleaninline{setSds}.
 This task yields the written value as a stable result after it is done writing.
-Getting and immediately after setting \pgls{SDS} is not necessarily an \emph{atomic} operation in \gls{MTASK} because it is possible that another task accesses the \gls{SDS} in between.
-To circumvent this issue, \cleaninline{updSds} is created, this task atomically updates the value of the \gls{SDS}.
+Getting and immediately setting \pgls{SDS} is not necessarily an \emph{atomic} operation in \gls{MTASK} because it is possible that another task accesses the \gls{SDS} in between.
+To circumvent this issue, \cleaninline{updSds} is available by which \pgls{SDS} can be atomically updated.
 The \cleaninline{updSds} task only guarantees atomicity within \gls{MTASK}.
 
 \begin{lstClean}[label={lst:mtask_sds},caption={\Glspl{SDS} in \gls{MTASK}.}]
@@ -484,30 +614,95 @@ class sds v where
        updSds :: (v (Sds t)) ((v t) -> v t) -> MTask v t
 \end{lstClean}
 
-\Cref{lst:mtask_sds_examples} shows an example using \glspl{SDS}.
+\Cref{lst:mtask_sds_examples} shows an example task that uses \glspl{SDS}.
 The \cleaninline{count} function takes a pin and returns a task that counts the number of times the pin is observed as high by incrementing the \cleaninline{share} \gls{SDS}.
-In the \cleaninline{main} expression, this function is called twice and the results are combined using the parallel or combinator (\cleaninline{.||.}).
-Using a sequence of \cleaninline{getSds} and \cleaninline{setSds} would be unsafe here because the other branch might write their old increment value immediately after writing, effectively missing a count.\todo{beter opschrijven}
+In the \cleaninline{main} expression, this function is called twice with a different argument.
+The results are combined using the parallel disjunction combinator (\cleaninline{.\|\|.}).
+Using a sequence of \cleaninline{getSds} and \cleaninline{setSds} would be unsafe here because the other branch might write their old increment value immediately after writing, effectively missing a count.
 
 \begin{lstClean}[label={lst:mtask_sds_examples},caption={Examples with \glspl{SDS} in \gls{MTASK}.}]
 task :: MTask v Int | mtask v
-task = declarePin D3 PMInput \d3->
+task =
+       declarePin D3 PMInput \d3->
        declarePin D5 PMInput \d5->
           sds \share=0
        In fun \count=(\pin->
                    readD pin
-               >>* [IfValue (\x->x) (\_->updSds (\x->x +. lit 1) share)]
+               >>* [IfValue id (\_->updSds (\x->x +. lit 1) share)]
                >>| delay (lit 100) // debounce
                >>| count pin)
        In {main=count d3 .||. count d5}
 \end{lstClean}
 
+\section{Interpretations}
+\todo[inline]{Iets meer uitleg over waarom dit zo handig is}
+This section describes all the interpretations that the \gls{MTASK} language has to offer.
+Not all these interpretations are necessarily \gls{TOP} engines, i.e.\ not all the interpretations execute the resulting tasks.
+Some may perform an analysis over the program or typeset the program.
+
+\subsection{Pretty printer}
+The pretty printer interpretation converts an \gls{MTASK} term to a string representation.
+As the host language \gls{CLEAN} constructs the \gls{MTASK} expressions at run time, it can be useful to show the constructed expression at run time as well.
+The only function exposed for this interpretation is the \cleaninline{showMain} function (\cref{lst:showmain}).
+It runs the pretty printer and returns a list of strings containing the pretty printed result.
+The pretty printing function does the best it can but obviously cannot reproduce layout, curried functions, and variable names.
+This shortcoming is illustrated by printing a blink task that contains a function and currying in \cref{lst:showexample}.
+
+\begin{lstClean}[caption={The entry point for the pretty printing interpretation.},label={lst:showmain}]
+:: Show a // from the mTask pretty printing library
+showMain :: (Main (Show a)) -> [String]
+\end{lstClean}
+
+\begin{lstClean}[caption={Pretty printing interpretation example.},label={lst:showexample}]
+blinkTask :: Main (MTask v Bool) | mtask v
+blinkTask =
+       fun \blink=(\state->
+               writeD d13 state >>|. delay (lit 500) >>=. blink o Not
+       ) In {main = blink true}
+
+// output when printing:
+// fun f0 a1 = writeD(D13, a1) >>= \a2.(delay 1000)
+//     >>| (f0 (Not a1)) in (f0 True)
+\end{lstClean}
+
+\subsection{Simulator}
+The simulator converts the expression to a ready-for-work \gls{ITASK} simulation.
+There is one entry point for this interpretation (see \cref{lst:simulatemain}).
+The task resulting from the \cleaninline{simulate} function presents the user with an interactive simulation environment (see \cref{fig:sim}).
+The simulation allows the user to (partially) execute tasks, control the simulated peripherals, inspect the internal state of the tasks, and interact with \glspl{SDS}.
+
+\begin{lstClean}[caption={The entry point for the simulation interpretation.},label={lst:simulatemain}]
+:: TraceTask a // from the mTask simulator library
+simulate :: (Main (TraceTask a)) -> [String]
+\end{lstClean}
+
+\begin{figure}
+       \centering
+       \includegraphics[width=\linewidth]{simg}
+       \caption{Simulator interface for a blink program written in \gls{MTASK}.}\label{fig:sim}
+\end{figure}
+
+\subsection{Byte code compiler}
+The main interpretation of the \gls{MTASK} system is the byte code compiler (\cleaninline{:: BCInterpret a}).
+This interpretation compiles the \gls{MTASK} term at run time to byte code.
+With it, and a handful of integration functions, \gls{MTASK} tasks can be executed on microcontrollers and integrated in \gls{ITASK} as if they were regular \gls{ITASK} tasks.
+Furthermore, with a special language construct, \glspl{SDS} can be shared between \gls{MTASK} and \gls{ITASK} programs as well.
+The integration with \gls{ITASK} is explained thoroughly later in \cref{chp:integration_with_itask}.
+
+The \gls{MTASK} language together with \gls{ITASK} is a heterogeneous \gls{DSL}.
+I.e.\ some components---for example the \gls{RTS} on the microcontroller that executes the tasks---is largely unaware of the other components in the system, and it is executed on a completely different architecture.
+The \gls{MTASK} language is a \gls{TOP} language with basic tasks tailored for \gls{IOT} edge devices (see \cref{sec:top}).
+It uses expressions based a simply-typed $\lambda$-calculus with support for some basic types, arithmetic operations, and function definitions.
+
 \section{Conclusion}
-\Gls{MTASK} is a rich \gls{TOP} language tailored for \gls{IOT} systems.
-It is embedded in the pure functional language \gls{CLEAN} and uses an enriched lambda calculus as a host language.
-It provides support for all common arithmetic expressions, conditionals, functions, but also several basic tasks, task combinators, peripheral support and integration with \gls{ITASK}.
-By embedding domain-specific knowledge in the language itself, it achieves the same abstraction level and dynamicity as other \gls{TOP} languages while targetting tiny computers instead.
-As a result, a single declarative specification can describe an entire \gls{IOT} system.
+This chapter gave an overview of the complete \gls{MTASK} \gls{DSL}.
+The \gls{MTASK} language is a rich \gls{TOP} language tailored for \gls{IOT} edge devices.
+The language is implemented as a class-based shallowly \gls{EDSL} in the pure functional host language \gls{CLEAN}.
+The language is an enriched lambda calculus as a host language.
+It provides language constructs for arithmetic expressions, conditionals, functions, but also non-interactive basic tasks, task combinators, peripheral support, and integration with \gls{ITASK}.
+Terms in the language are just interfaces and can be interpreted by one or more interpretations.
+When using the byte code compiler, terms in the \gls{MTASK} language are type checked at compile time but are constructed and compiled at run time.
+This facilitates tailor-making tasks for the current work requirements.
 
 \input{subfilepostamble}
 \end{document}