proofread chp 4
authorMart Lubbers <mart@martlubbers.net>
Thu, 2 Feb 2023 19:05:48 +0000 (20:05 +0100)
committerMart Lubbers <mart@martlubbers.net>
Thu, 2 Feb 2023 19:05:48 +0000 (20:05 +0100)
preamble.tex
top/lang.tex

index 88ef752..20cef3a 100644 (file)
 \newcommand{\Imtask}{\Gls{ITASK}\slash\gls{MTASK}}
 \newcommand{\citask}{\gls{CLEAN}\slash\gls{ITASK}}
 \newcommand{\Citask}{\Gls{CLEAN}\slash\gls{ITASK}}
+\newcommand{\cmtask}{\gls{CLEAN}\slash\gls{MTASK}}
+\newcommand{\Cmtask}{\Gls{CLEAN}\slash\gls{MTASK}}
 \newcommand{\cimtask}{\gls{CLEAN}\slash\gls{ITASK}\slash\gls{MTASK}}
 \newcommand{\Cimtask}{\Gls{CLEAN}\slash\gls{ITASK}\slash\gls{MTASK}}
 \newcommand{\ccpp}{\gls{C}\slash\gls{CPP}}
index 2c5cb70..09b4f2b 100644 (file)
@@ -9,9 +9,9 @@
 \chapter{The \texorpdfstring{\gls{MTASK}}{mTask} language}%\texorpdfstring{\glsxtrshort{DSL}}{DSL}}%
 \label{chp:mtask_dsl}
 \begin{chapterabstract}
-       This chapter introduces the \gls{TOP} language \gls{MTASK} language by:
+       This chapter introduces the \gls{TOP} language \gls{MTASK} by:
        \begin{itemize}
-               \item introducing the setup of the \gls{EDSL};
+               \item introducing the setup of the language;
                \item describing briefly the various interpretations;
                \item and showing the language interface for:
                        \begin{itemize}
 The \gls{MTASK} system is a complete \gls{TOP} programming environment for programming microcontrollers.
 This means that it not only contains a \gls{TOP} language but also a \gls{TOP} engine.
 Due to the nature of the embedding technique, it is possible to have multiple interpretations for programs written in the \gls{MTASK} language.
-As the language is implemented as an \gls{EDSL} in \gls{CLEAN} using class-based---or tagless-final---embedding (see \cref{sec:tagless-final_embedding}).
-This means that the language is a collection of type classes and interpretations are data types implementing these classes.
-Consequently, the language is extensible both in language constructs and in intepretations.
+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.
+This particular type of embedding results in the language being is extensible both in language constructs and in intepretations.
 Adding a language construct is as simple as adding a type class and adding an interpretation is done by creating a new data type and providing implementations for the various type classes.
-Let us illustrate this by taking the very simple language of literal values.
+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 a values, as long as 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
@@ -40,7 +42,7 @@ class literals v where
 \end{lstClean}
 
 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 could also be some monadic computation.
+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.
 
 \begin{lstClean}
 :: Eval a = Eval a
@@ -53,7 +55,7 @@ instance literals Eval where
 \end{lstClean}
 
 Extending our language with a printer happens by defining a new data type and providing instances for the type constructor classes.
-The printer stores a printed representation and hence the type is just a phantom type.
+The printer shown below only stores a printed representation and hence the type is just a phantom type:
 
 \begin{lstClean}
 :: Printer a = Printer String
@@ -65,8 +67,8 @@ instance literals Printer where
        lit a = Printer (toString a)
 \end{lstClean}
 
-Finally, adding language constructs happens by defining new type classes and giving implementations for some of the interpretations.
-The following listing adds an addition construct to the language and shows implementations for the evaluator and printer.
+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
@@ -79,26 +81,26 @@ instance addition Printer where
        add (Printer l) (Printer r) = Printer ("(" +++ l +++ "+" +++ r +++ ")")
 \end{lstClean}
 
-Terms in our little toy language can be overloaded in their interpretation, they are just an interface.
+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 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{Interpretations}
-This section describes all \gls{MTASK}'s interpretations.
-Not all of these interpretations are necessarily \gls{TOP} engines, i.e.\ not all of the interpretations execute the terms/tasks.
+This section describes all the interpretations tha the \gls{MTASK} language has.
+Not all of these interpretations are necessarily \gls{TOP} engines, i.e.\ not all of the interpretations execute the resulting tasks.
 Some may perform an analysis over the program or typeset the program so that a textual representation can be shown.
 
 \subsection{Pretty printer}
-This interpretation converts the expression 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.
-The only function exposed for this interpretation is the \cleaninline{showMain} (\cref{lst:showmain}) function.
-It runs the pretty printer and returns a list of strings containing the pretty printed result as shown in \cref{lst:showexample}.
-The pretty printing function does the best it can but obviously cannot reproduce the layout, curried functions and variable names.
-This shortcoming is illustrated by the example application for blinking a single \gls{LED} using a function and currying in \cref{lst:showexample}.
+The pretty printer interpretation converts the expression 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 the 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 entrypoint for the pretty printing interpretation.},label={lst:showmain}]
-:: Show a // from the mTask Show library
+:: Show a // from the mTask pretty printing library
 showMain :: (Main (Show a)) -> [String] | type a
 \end{lstClean}
 
@@ -110,16 +112,17 @@ blinkTask =
        ) In {main = blink true}
 
 // output:
-// fun f0 a1 = writeD(D13, a1) >>= \a2.(delay 1000) >>| (f0 (Not a1)) in (f0 True)
+// 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 in which the user can inspect and control the simulated peripherals and see the internal state of the tasks.
+The simulator converts the expression to a ready-for-work \gls{ITASK} simulation.
 The task resulting from the \cleaninline{simulate} function presents the user with an interactive simulation environment (see \cref{lst:simulatemain,fig:sim}).
-From within the interactive application, tasks can be (partly) executed, peripheral states changed and \glspl{SDS} interacted with.
+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 entrypoint for the simulation interpretation.},label={lst:simulatemain}]
-:: TraceTask a // from the mTask Show library
+:: TraceTask a // from the mTask simulator library
 simulate :: (Main (TraceTask a)) -> [String] | type a
 \end{lstClean}
 
@@ -130,31 +133,33 @@ simulate :: (Main (TraceTask a)) -> [String] | type a
 \end{figure}
 
 \subsection{Byte code compiler}
-The main interpretation of the \gls{MTASK} system is the byte code compiler.
+The main interpretation of the \gls{MTASK} system is the byte code compiler (\cleaninline{:: BCInterpret}).
 With it, and 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 a special language construct, \glspl{SDS} can be shared between \gls{MTASK} and \gls{ITASK} programs as well.
-This interface is explained thoroughly in \cref{chp:integration_with_itask}.
+For this chapter, the focus lies on the language itself.
+The integration with \gls{ITASK} is explained thoroughly later in \cref{chp:integration_with_itask}.
 
 When using the byte code compiler interpretation in conjunction with the \gls{ITASK} integration, \gls{MTASK} is a heterogeneous \gls{DSL}.
-I.e.\ some components---for example 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}).
+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 based on a simply-typed $\lambda$-calculus with support for some basic types, arithmetic operations, and function definitions.
+This basic language is enriched with a task language to make it \gls{TOP} (see \cref{sec:top}).
 
 \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.
+Many of these functions are usually automatically derived using generic programming but can be specialised when needed.
 An even stronger restriction on types 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.
+The class constraints for values in \gls{MTASK} are omnipresent in all functions and therefore usually omitted throughout throughout the chapters for brevity and clarity.
 
 \begin{table}[ht]
        \centering
-       \caption{Translation from \gls{CLEAN}\slash\gls{MTASK} data types to \ccpp{} datatypes.}%
+       \caption{Translation from \cmtask{} data types to \ccpp{} datatypes.}%
        \label{tbl:mtask-c-datatypes}
        \begin{tabular}{lll}
                \toprule
-               \gls{CLEAN}\slash\gls{MTASK} & \ccpp{} type & \textnumero{}bits\\
+               \cmtask{} & \ccpp{} type & \textnumero{}bits\\
                \midrule
                \cleaninline{Bool}             & \cinline{bool}    & 16\\
                \cleaninline{Char}             & \cinline{char}    & 16\\
@@ -169,20 +174,24 @@ The class constraints for values in \gls{MTASK} are omnipresent in all functions
 \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.
 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.
+There are also \gls{MTASK} extensions that not every interpretation implements and are thus not included in the \cleaninline{mtask} class collection such as peripherals and \gls{ITASK} integration.
+
 \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 ...
 
 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.
+This is enforced by the \cleaninline{Main} type.
+Most 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.
+An example of this can be seen in \cleaninline{someTask} shown in \cref{lst:mtask_types}.
 
+% VimTeX: SynIgnore on
 \begin{lstClean}[caption={Example task and auxiliary types 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
 
@@ -192,30 +201,28 @@ someTask =
        sensor2 config2 \sns2->
           sds     \s1  = initialValue
        In liftsds \s2  = someiTaskSDS
-       In fun     \fun1= ( ... )
-       In fun     \fun2= ( ... )
+       In fun     \fun1= ( \(a0, a1)->... )
+       In fun     \fun2= ( \a->... )
        In { main = mainexpr }
 \end{lstClean}
+% VimTeX: SynIgnore off
 
-\Gls{MTASK} expressions are usually overloaded in their interpretation (\cleaninline{v}).
+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}\citep[\citesection{3.7.4}]{plasmeijer_clean_2021}.
 \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.
 
 \begin{lstClean}[label={lst:rank2_mtask},caption={Rank-2 polymorphism to allow multiple interpretations}]
-prettyPrint :: Main (MTask PrettyPrint a) -> String
-simulate :: Main (MTask Simulate a) -> Task a
-
 simulateAndPrint :: (A.v: Main (MTask v a) | mtask v) -> Task a | type a
 simulateAndPrint mt =
            simulate mt
-       -|| Hint "Current task:" @>> viewInformation [] (prettyPrint mt)
+       -|| Hint "Current task:" @>> viewInformation [] (showMain mt)
 \end{lstClean}
 
 \section{Expressions}\label{sec:expressions}
 This section shows all \gls{MTASK} constructs for exppressions.
-\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.
+\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 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.
 
 \begin{lstClean}[caption={The \gls{MTASK} class for expressions},label={lst:expressions}]
@@ -231,7 +238,8 @@ 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}.}]
@@ -241,48 +249,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 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.
+\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 a simple approximate equality---albeit without taking into account all floating point pecularities.
-When calling \cleaninline{approxEqual} in an \gls{MTASK} function, the resulting code is inlined.
+The \gls{MTASK} language is shallowly embedded in \gls{CLEAN} and the terms are constructed at run time.
+This means that \gls{MTASK} programs can also be tailor-made at run time or constructed using \gls{CLEAN} functions maximising the linguistic reuse \citep{krishnamurthi_linguistic_2001}.
+The \cleaninline{approxEqual} function in \cref{lst:example_macro} performs a simple approximate equality---admittedly not taking into account all floating point pecularities.
+When calling \cleaninline{approxEqual} in an \gls{MTASK} expression, the resulting code is inlined.
 
-\begin{lstClean}[label={lst:example_macro},caption={Example linguistic reuse in the \gls{MTASK} language.}]
+\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 Real | expr v
-approxEqual x y eps = if' (x ==. y) true
-       ( if' (x >. y)
-               (y -. x < eps)
-               (x -. y < eps)
+approxEqual x y eps = If (x ==. y) true
+       ( If (x >. y)
+               (x -. y <. eps)
+               (y -. x <. eps)
        )
 \end{lstClean}
 
 \subsection{Data types}
-Most of \gls{CLEAN}'s fixed-size basic types are 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}).
+Most of \gls{CLEAN}'s fixed-size basic types 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} must have a fixed-size representation on the stack so sum types are not (yet) supported.
+While it is possible to lift any 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 or deconstructors 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}.
+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 for using tuples can be found 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
@@ -294,45 +302,46 @@ class tupl v where
 \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 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 or 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 tuples for the arguments, partial function applications is eradicated.
+The definition of the type class and the 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.
+\Cref{lst:function_examples} show some examples of functions to demonstrate the syntax for functions.
 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.
 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.
+In the \cleaninline{factorialtail} function, a tail-call optimised version of the factorial function, a manually added class constraint can be seen.
+Definiting zero arity functions, always called with the unit as an argument, is shown 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}.}]
 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))
@@ -353,16 +362,22 @@ swapTuple =
 
 \section{Tasks and task combinators}\label{sec:top}
 This section describes \gls{MTASK}'s task language.
-\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.
+Tasks can be seen as trees that are the result of evaluating expressions.
+After evaluating an expression, the resulting task is executed.
+\todo[inline]{iets zeggen over values en dat hier ook een handwavy semantiek is.}
+The execution semantics of tasks is explained in more detail in \cref{chp:implementation}.
+The task language of \gls{MTASK} is divided into three categories, namely
+\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 \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.
+       \item [Task combinators] provide a way of describing the workflow.
                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 references to data 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}, an expression of the type \cleaninline{TaskValue a} in interpretation \cleaninline{v}.
 
 \begin{lstClean}[label={lst:task_type},caption={Task type in \gls{MTASK}.}]
@@ -390,12 +405,12 @@ class delay v :: (v n) -> MTask v n | long v n
 
 \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.
+The type classes for these tasks are not included in the \cleaninline{mtask} class collection as not all devices nor all language interpretations support all peripherals connected.
 
-\Cref{lst:dht,lst:gpio} show the type classes for \glspl{DHT} sensors and \gls{GPIO} access.
+\Cref{lst:dht} shows the type classes for \glspl{DHT} sensors.
 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.
+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 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 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.
 
 \begin{lstClean}[label={lst:dht},caption={The \gls{MTASK} interface for \glspl{DHT} sensors.}]
@@ -414,16 +429,17 @@ 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 (see \cref{lst:gpio}).
+\todo[inline]{Uitleggen wat GPIO is}
+\Gls{GPIO} access is divided into three classes: analogue \gls{IO}, digital \gls{IO} and pin modes configuration (see \cref{lst:gpio}).
 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 \cleaninline{pin} type class allows functions to be overloaded in either the analog or digital pins, e.g.\ analog pins can be considered as digital pins as well.
+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 as 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}.
-Analog \gls{GPIO} tasks are bundled in the \cleaninline{aio} type class.
+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.
@@ -453,7 +469,7 @@ class pinMode v where
 \end{lstClean}
 
 \Cref{lst:gpio_examples} shows two examples of \gls{MTASK} tasks using \gls{GPIO} pins.
-\cleaninline{task1} reads analog \gls{GPIO} pin 3.
+\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.
@@ -470,17 +486,18 @@ task2 = declarePin D3 PMOutput \d3->{main=writeD d3 true}
 Task combinators are used to combine multiple tasks to describe workflows.
 In contrast to \gls{ITASK}, that uses super combinators to derive the simpler ones, \gls{MTASK} 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*}
+\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*}
+\end{enumerate}
 
 \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 expressed in the \cleaninline{step} class and can be---and are by default---derived from the Swiss army knife step combinator \cleaninline{>>*.}.
 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.
+The list of task continuations is checked during evaluation of the left-hand side and if one of the predicates matches, the task continues with the result of this combination.
+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.
 The \cleaninline{>>~.} and \cleaninline{>>..} combinators are variants of the ones above that ignore the stability and continue on an unstable value as well.
@@ -503,9 +520,8 @@ class step v | expr v where
 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 >>*.
@@ -515,7 +531,7 @@ readPinBin lim = declarePin PMInput A2 \a2->
 \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 actually results in both tasks being executed at the same time.
 There are two types of parallel task combinators (see \cref{lst:mtask_parallel}).
 
 \begin{lstClean}[label={lst:mtask_parallel},caption={Parallel task combinators in \gls{MTASK}.}]
@@ -526,7 +542,7 @@ class (.||.) infixr 3 v :: (MTask v a) (MTask v a) -> MTask v a
 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 disjunction combinator (\cleaninline{.\|\|.}) combines the results by picking the leftmost, stablest task.
 The semantics are most easily described using the \gls{CLEAN} functions shown in \cref{lst:semantics_con,lst:semantics_dis}.
 
 \begin{figure}[ht]
@@ -555,9 +571,9 @@ dis (Value l ls) (Value r rs)
        \end{subfigure}
 \end{figure}
 
-\Cref{lst:mtask_parallel_example} gives an example program using 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{.&&.} instead, 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
@@ -569,8 +585,9 @@ task =
 \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.
+In many workflows, tasks are to be executed continuously.
+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 in \cref{lst:blinkthreadmtask}.
 
 \begin{lstClean}[label={lst:mtask_repeat},caption={Repeat task combinators in \gls{MTASK}.}]
@@ -578,10 +595,10 @@ 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.
+To demonstrate the combinator, \cref{lst:mtask_repeat_example} shows the \cleaninline{rpeat} combinator in use.
+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={Exemplary 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->
@@ -590,6 +607,7 @@ task =
 \end{lstClean}
 
 \subsection{\texorpdfstring{\Glsxtrlongpl{SDS}}{Shared data sources}}
+\todo[inline]{Explain \glspl{SDS} shortly.}
 \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.
 The \cleaninline{getSds} task yields the current value of the \gls{SDS} as an unstable value.
@@ -597,7 +615,7 @@ 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}.
+To circumvent this issue, \cleaninline{updSds} is available by which \pgls{SDS} can be atomacally updated.
 The \cleaninline{updSds} task only guarantees atomicity within \gls{MTASK}.
 
 \begin{lstClean}[label={lst:mtask_sds},caption={\Glspl{SDS} in \gls{MTASK}.}]
@@ -609,7 +627,7 @@ 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}
@@ -628,11 +646,12 @@ task = declarePin D3 PMInput \d3->
 \end{lstClean}
 
 \section{Conclusion}
-\Gls{MTASK} is a rich \gls{TOP} language tailored for \gls{IOT} systems.
+The \gls{MTASK} language is a rich \gls{TOP} language tailored for \gls{IOT} edge devices.
 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.
+\todo[inline]{Uitbreiden?}
 
 \input{subfilepostamble}
 \end{document}