myriad of typos
authorMart Lubbers <mart@martlubbers.net>
Wed, 22 Feb 2023 09:59:35 +0000 (10:59 +0100)
committerMart Lubbers <mart@martlubbers.net>
Wed, 22 Feb 2023 09:59:35 +0000 (10:59 +0100)
21 files changed:
appx/c4hp.tex
appx/mtask_aux.tex
back/acknowledgements.tex
back/curriculum_vitae.tex
back/research_data_management.tex
back/summary.tex
check.txt [deleted file]
concl/concl.tex
dsl/class.tex
dsl/first.tex
glossary.bash [new file with mode: 0644]
intro/intro.tex
preamble/glossaries.tex
top/4iot.tex
top/finale.tex
top/green.tex
top/imp.tex
top/int.tex
top/lang.tex
top/top.tex
tvt/tvt.tex

index 8ee7fb1..ba0b019 100644 (file)
@@ -8,9 +8,9 @@
 \chapter{Clean for Haskell programmers}%
 \label{chp:clean_for_haskell_programmers}
 
-This appendix is meant give people who are familiar with the \gls{FP} language \gls{HASKELL} a consise overview of the programming language \gls{CLEAN} and how it differs from \gls{HASKELL}.
+This appendix is meant give people who are familiar with the \gls{FP} language \gls{HASKELL} a concise overview of the programming language \gls{CLEAN} and how it differs from \gls{HASKELL}.
 The goal is to support the reader when reading \gls{CLEAN} code.
-\Cref{tbl:syn_clean_haskell} shows frequently occuring \gls{CLEAN} language elements on the left side and their \gls{HASKELL} equivalent on the right side.
+\Cref{tbl:syn_clean_haskell} shows frequently occurring \gls{CLEAN} language elements on the left side and their \gls{HASKELL} equivalent on the right side.
 Obviously, this summary is not exhaustive.
 Some \gls{CLEAN} language elements that are not easily translatable to \gls{HASKELL} and thus do not occur in the summary following below.
 We hope you enjoy these notes and that it aids you in reading \gls{CLEAN} programs.
@@ -21,10 +21,10 @@ Fast-forward thirty years, \gls{CLEAN} is now a robust language with state-of-th
 
 Initially, when it was used mostly as an intermediate language, it had a fairly spartan syntax.
 However, over the years, the syntax got friendlier and it currently it looks a lot like \gls{HASKELL}.
-In the past, a \emph{double-edged} fronted even existed that allowed \gls{CLEAN} to be extended with \gls{HASKELL98} syntax and vice versa \citep{van_groningen_exchanging_2010}, however this frontend is no longer maintained.
+In the past, a \emph{double-edged} fronted even existed that allowed \gls{CLEAN} to be extended with \gls{HASKELL}98 syntax and vice versa \citep{van_groningen_exchanging_2010}, however this frontend is no longer maintained.
 This chapter gives only a brief syntactical and functional comparison.
 A complete specification of the \gls{CLEAN} language can be found in the latest language report \citep{plasmeijer_clean_2021}.
-Much of this is based on work by Achten, although that was based on \gls{CLEAN} 2.1 and \gls{HASKELL98} \citep{achten_clean_2007}.
+Much of this is based on work by Achten, although that was based on \gls{CLEAN} 2.1 and \gls{HASKELL}98 \citep{achten_clean_2007}.
 When \gls{HASKELL} is mentioned we actually mean \gls{GHC}'s \gls{HASKELL}\footnote{If an extension is enabled, a footnote is added stating that \GHCmod{SomeExtension} is required.} and by \gls{CLEAN} we mean \gls{CLEAN} 3.1's compiler with the \gls{ITASK} extensions.
 
 \section{Features}
@@ -94,7 +94,7 @@ readChars file
 \end{lstClean}
 
 \subsection{Generics}
-Polytypic functions \citep{jeuring_polytypic_1996}---also known as generic or kind-indexed fuctions---are built into \gls{CLEAN} \citep[\citesection{7.1}]{plasmeijer_clean_2021}\citep{alimarine_generic_2005} whereas in \gls{HASKELL} they are implemented as a library \citep[\citesection{6.19.1}]{ghc_team_ghc_2021}.
+Polytypic functions \citep{jeuring_polytypic_1996}---also known as generic or kind-indexed functions---are built into \gls{CLEAN} \citep[\citesection{7.1}]{plasmeijer_clean_2021}\citep{alimarine_generic_2005} whereas in \gls{HASKELL} they are implemented as a library \citep[\citesection{6.19.1}]{ghc_team_ghc_2021}.
 The syntax of the built-in generics of \gls{CLEAN} is very similar to that of Generic H$\forall$skell \citep{hinze_generic_2003}.
 %When calling a generic function, the kind must always be specified and depending on the kind, the function may require more arguments.
 
index 220053a..28532c2 100644 (file)
@@ -11,7 +11,7 @@
 \section{Peripherals}\label{sec:aux_peripherals}
 This section shows the peripherals not mentioned in \cref{chp:top4iot}.
 All constructors use \gls{HOAS} to create a type safe sensor object from a connection specification that can be used to interact with the sensor.
-The measurement tasks all yield unstable values contaning the measured value.
+The measurement tasks all yield unstable values containing the measured value.
 The auxiliary functions such as calibration yield stable values indicating the result.
 Tasks suffixed with the backtick (\cleaninline{'}) indicate variants for which the timing interval can be specified (see \cref{chp:green_computing_mtask}).
 
@@ -35,7 +35,7 @@ class AirQualitySensor v where
 
 \subsection{Gesture sensor}
 The \gls{MTASK} language supports one type (\emph{PAJ7620} connected via \gls{I2C}) of gesture sensors.
-The \emph{PAJ7620} contains an optical CMOS array that measures the reflection of the on-board \gls{IR} \gls{LED} to detect up to several different gestures.
+The \emph{PAJ7620} contains an optical CMOS array that measures the reflection of the on-board \gls{IR} \gls{LED} to detect up to several gestures.
 The complete interface containing the constructor and the measurement task is shown in \cref{lst:mtask_gesture}.
 
 \begin{lstClean}[label={lst:mtask_gesture},caption={Gesture sensor interface in \gls{MTASK}.}]
@@ -64,7 +64,7 @@ class LightSensor v where
 
 \subsection{Motion detection sensor}
 The \gls{MTASK} language supports motion sensing using a \gls{PIR} sensor through a type class that only contains macros.
-\gls{PIR} sensors detect motion by the \gls{IR} reflection through a number of fresnel lenses and communicates through a digital \gls{GPIO} pin.
+\gls{PIR} sensors detect motion by the \gls{IR} reflection through a number of Fresnel lenses and communicates through a digital \gls{GPIO} pin.
 Therefore, a \gls{PIR} is nothing more than a \cleaninline{DPIN} according to \gls{MTASK} but for uniformity, a type class is available (see \cref{lst:mtask_pir}).
 
 \begin{lstClean}[label={lst:mtask_pir},caption={\Gls{PIR} sensor interface in \gls{MTASK}.}]
@@ -97,7 +97,7 @@ where
 \end{lstClean}
 
 \subsection{\IIC{} buttons}
-The \gls{MTASK} language supports one type of \gls{I2C} buttons (the \gls{I2C} buttons from the \gls{WEMOS} d1 mini \gls{OLED} shield).
+The \gls{MTASK} language supports one type of \gls{I2C} buttons (the \gls{I2C} buttons from the \gls{WEMOS} D1 mini \gls{OLED} shield).
 The buttons from this shield provide more information than just the status (see \cleaninline{ButtonStatus}).
 The complete interface containing the constructor and the measurement tasks is shown in \cref{lst:mtask_i2cbutton}.
 
@@ -116,7 +116,7 @@ class i2cbutton v where
 \end{lstClean}
 
 \subsection{LED matrix}
-The \gls{MTASK} language supports one type of \gls{LED} matrix (the $8\times8$ \gls{LED} matrix shield for the \gls{WEMOS} d1 mini).
+The \gls{MTASK} language supports one type of \gls{LED} matrix (the $8\times8$ \gls{LED} matrix shield for the \gls{WEMOS} D1 mini).
 Instead of containing a \gls{TOP}-like interface, the \gls{ARDUINO} interface is directly translated to \gls{MTASK}.
 As a result, every task immediately returns a stable value indicating the result.
 The complete interface containing the constructor and the interaction tasks is shown in \cref{lst:mtask_ledmatrix}.
index f5a0f20..d8afe9a 100644 (file)
@@ -11,7 +11,7 @@ While the research and writing carried out for this thesis was mostly done by me
 
 First of all I would like to thank Rinus Plasmeijer, Pieter Koopman, and Jan Martin Jansen for the supervision, I learned a lot from you, not only regarding academia but in many other aspects of life as well.
 The BEST people, Adrian Ramsingh, Jeremy Singer, and Phil Trinder for the fruitful collaboration, and the memorable trip to Glasgow.
-The \glsxtrshort{CEFP}/SusTrainable group, for offering a platform for the various summer schools I had the opportunity to teach; and not to mention the countless meetings, dinners, and drinks we had.
+The \gls{3COWS}/SusTrainable group, for offering a platform for the various summer schools I had the opportunity to teach; and not to mention the countless meetings, dinners, and drinks we had.
 The Royal Dutch Navy, in particular Teun de Groot and Ton van Heusden, for trusting me by funding the project.
 \ldots
 %All the colleagues and others that I had the privilege of sharing an office with, meeting in conferences, interact with in the department, or work with in some other way:
index 8098844..abacbea 100644 (file)
@@ -17,7 +17,7 @@ Mart Lubbers
        2011{--}2015 & Bachelor's degree Artificial Intelligence at the Radboud University, Nijmegen\\
        2013{--}2015 & Research assistant at the Max Planck Institute for Psycholinguistics\\
        2015{--}2017 & Master's degree (cum laude) Computing Science (Software Science track) at the Radboud University, Nijmegen\\
-       2015{--}2017 & Entrepeneur as IT Lubbers, Nijmegen\\
+       2015{--}2017 & Entrepreneur as IT Lubbers, Nijmegen\\
        2017         & Researcher at the Netherlands Defense Academy, Den Helder in the faculty of Military Sciences (fMIL).\\
        2018         & Junior researcher at the Radboud University, Nijmegen in the Institute for Computing and Information Sciences (iCIS).\\
        2018{--}2023 & PhD candidate at the Radboud University, Nijmegen in the Institute for Computing and Information Sciences (iCIS).
index 4d241d8..3536462 100644 (file)
@@ -7,7 +7,7 @@
 \ifSubfilesClassLoaded{\chapter*{Research data management}}{\chapter{Research data management}}%
 \label{chp:research_data_management}
 
-This thesis research has been carried out under the research data management policy of the Institute for Computing and Information Science of Radboud University, the Netherlands\footnote{\refurl{https://www.ru.nl/icis/research-data-management/}{\formatdate{20}{1}{2020}}}.
+This thesis research has been carried out under the research data management policy of the Institute for Computing and Information Science of the Radboud University, the Netherlands\footnote{\refurl{https://www.ru.nl/icis/research-data-management/}{\formatdate{20}{1}{2020}}}.
 
 The following research datasets have been produced during this PhD research:
 \begin{itemize}
index 3713f33..0f1a927 100644 (file)
@@ -31,7 +31,7 @@ Then \gls{MTASK} is shown, a \gls{TOP} \gls{DSL} for \gls{IOT} edge devices, emb
 Tasks are constructed and compiled at run time.
 This allows tasks to be tailor-made for the current work requirements.
 The compiled task is sent to the device for interpretation.
-For a device to be used in an \gls{MTASK} system, it must to be programmed once with a lightweight domain-specific \gls{OS}.
+For a device to be used in an \gls{MTASK} system, it is programmed once with a lightweight domain-specific \gls{OS}.
 This \gls{OS} executes tasks in an energy-efficient way and automates all communications and data sharing.
 All aspects of the \gls{MTASK} system are shown: example applications, language design, implementation details, integration with \gls{ITASK}, and green computing facilities.
 When using \gls{MTASK} in conjunction with \gls{ITASK}, entire \gls{IOT} systems are programmed tierlessly from a single source, language, paradigm, high abstraction level, and type system.
diff --git a/check.txt b/check.txt
deleted file mode 100644 (file)
index b65dd16..0000000
--- a/check.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-undefined references
-overfull hboxes
-windows
-orphans
index 26db23f..5a75075 100644 (file)
@@ -26,10 +26,10 @@ Furthermore, \gls{IOT} systems become convoluted because they are dynamic, multi
 However, edge devices are often too computationally restricted to be able to run a full-fledged \gls{TOP} system such as \gls{ITASK}.
 The dissertation is structured as a purely functional rhapsody in three episodes.
 
-In order to get \gls{TOP} to resource-constraind edge devices we use special tools: \glspl{DSL}.
+In order to get \gls{TOP} to resource-constrained edge devices we use special tools: \glspl{DSL}.
 The dissertation shows several techniques for creating \glspl{EDSL}.
 Then it shows a tool, \gls{MTASK}, a \gls{TOP} system for \gls{IOT} edge devices.
-Finally it compares how this approach compares to existing approaches for programming \gls{IOT} systems.
+Finally, it compares how this approach compares to existing approaches for programming \gls{IOT} systems.
 
 \subsection{Tool craft}
 \Cref{prt:dsl} presents some tool crafting techniques that are useful for creating \gls{TOP} languages for \gls{IOT} edge devices.
@@ -69,7 +69,7 @@ Using tierless programming, many issues that arise with tiered programming are m
 This has already been observed in web applications.
 The \gls{MTASK} system show that it is possible to program edge devices of a \gls{IOT} systems using \gls{TOP}.
 Furthermore, when used together with \gls{ITASK}, entire \gls{IOT} systems can be programmed tierlessly.
-The question whether this novel approach to programming tiered systems also reduces the \gls{IOT} develop grief is answered in \cref{prt:tvt}.
+Whether this novel approach to programming tiered systems also reduces the \gls{IOT} develop grief is answered in \cref{prt:tvt}.
 This episode presents a four-way qualitative and quantitative comparison of the following systems:
 \gls{PRS}, a tiered system based on resource-rich edge devices powered by \gls{PYTHON};
 \gls{PWS}, a tiered system based on resource-constrained edge devices by \gls{MICROPYTHON};
index 083ad3c..c64bd44 100644 (file)
@@ -381,7 +381,7 @@ However, the implementation of semantics such as transformation or optimisation
 In shallow embedding, the implementation for these types of semantics is difficult because there is no tangible abstract syntax tree.
 In off-the-shelf deep embedding this is effortless since the function can pattern match on the constructor or structures of constructors.
 
-To demonstrate intensional analyses in classy deep embedding we write an optimizer that removes addition and subtraction by zero.
+To demonstrate intensional analyses in classy deep embedding we write an optimiser that removes addition and subtraction by zero.
 In classy deep embedding, adding new semantics means first adding a new type class housing the function including the machinery for the extension constructor.
 
 \begin{lstHaskellLhstex}
@@ -400,7 +400,7 @@ instance Opt_3 v => GDict (OptDict_3 v) where
        gdict = OptDict_3 opt_3
 \end{lstHaskellLhstex}
 
-The implementation of the optimizer for the \haskelllhstexinline{Expr_3} data type is no complicated task.
+The implementation of the optimiser for the \haskelllhstexinline{Expr_3} data type is no complicated task.
 The only interesting bit occurs in the \haskelllhstexinline{Add_3} constructor, where we pattern match on the optimised children to determine whether an addition with zero is performed.
 If this is the case, the addition is removed.
 
@@ -539,7 +539,7 @@ e1 = neg_4 (Lit_4 42 `Add_4` Lit_4 38) `sub_4` Lit_4 0
 \end{lstHaskellLhstex}
 
 When using classy deep embedding to the fullest, the ability of the compiler to infer very general types expires.
-As a consequence, defining reusable expressions that are overloaded in their semantics requires quite some type class constraints that cannot be inferred by the compiler (yet) if they use many extensions.
+As a consequence, defining reuseable expressions that are overloaded in their semantics requires quite some type class constraints that cannot be inferred by the compiler (yet) if they use many extensions.
 Solving this remains future work.
 For example, the expression $\sim(42-38)+1$ has to be defined as:
 
@@ -575,7 +575,7 @@ data Not_g  d a where
        NotLoop_g :: Expr_g d a    -> Not_g d a
 \end{lstHaskellLhstex}
 
-The smart constructors for the language extensions inherit the class constraints of their data types and include a \haskelllhstexinline{Typeable} constraint on the \haskelllhstexinline{d} type variable for it to be usable in the \haskelllhstexinline{Ext_g} constructor as can be seen in the smart constructor for \haskelllhstexinline{Neg_g}:
+The smart constructors for the language extensions inherit the class constraints of their data types and include a \haskelllhstexinline{Typeable} constraint on the \haskelllhstexinline{d} type variable for it to be useable in the \haskelllhstexinline{Ext_g} constructor as can be seen in the smart constructor for \haskelllhstexinline{Neg_g}:
 
 \begin{lstHaskellLhstex}
 neg_g  :: (Typeable d, GDict (d (Neg_g d)), Typeable a, Num a) =>
@@ -602,7 +602,7 @@ class Opt_g   v where
 Now that the shape of the type classes has changed, the dictionary data types and the type classes need to be adapted as well.
 The introduced type variable \haskelllhstexinline{a} is not an argument to the type class, so it should not be an argument to the dictionary data type.
 To represent this type class function, a rank-2 polymorphic function is needed \citep[\citesection{6.4.15}]{ghc_team_ghc_2021}\citep{odersky_putting_1996}.
-Concretely, for the evaluatior this results in the following definitions:
+Concretely, for the evaluator this results in the following definitions:
 
 \begin{lstHaskellLhstex}
 newtype EvalDict_g v = EvalDict_g (forall a. v a -> a)
@@ -669,7 +669,7 @@ For example, \citet{svenningsson_combining_2013} show that by expressing the dee
 Classy deep embedding differs from the hybrid approaches in the sense that it does not require the language extensions to be expressible in the core language.
 
 \subsection{Comparison}
-No \gls{DSL} embedding technique is the silver bullet, there is no way of perfectly satisfying all requiremens programmers have.
+No \gls{DSL} embedding technique is the silver bullet, there is no way of perfectly satisfying all requirements programmers have.
 \Citet{sun_compositional_2022} provided a thorough comparison of embedding techniques including more axes than just the two stated in the expression problem.
 
 \Cref{tbl:dsl_comparison_brief} shows a variant of their comparison table.
@@ -677,7 +677,7 @@ The first two rows describe the two axes of the original expression problem and
 The \emph{poly.} style of embedding---including tagless-final---falls short of this requirement.
 
 Intensional analysis is an umbrella term for pattern matching and transformations.
-In shallow embedding, intensional analysis is more complex and requires stateful views describing context but it is possible to implement though.
+In shallow embedding, intensional analysis is more complex and requires stateful views describing context, but it is possible to implement though.
 
 Simple type system describes the whether it is possible to encode this embedding technique without many type system extensions.
 In classy deep embedding, there is either a bit more scaffolding and boilerplate required or advanced type system extensions need to be used.
@@ -737,7 +737,7 @@ The basic technique only requires---well established through history and relativ
 However, if needed, the technique generalises to \glspl{GADT} as well, adding rank-2 types to the list of type system requirements as well.
 Finally, the abstract syntax tree remains observable which makes it suitable for intensional analyses, albeit using occasional dynamic typing for truly cross-extensional transformations.
 
-Defining reusable expressions overloaded in semantics or using multiple semantics on a single expression requires some boilerplate still, getting around this remains future work.
+Defining reuseable expressions overloaded in semantics or using multiple semantics on a single expression requires some boilerplate still, getting around these issues remains future work.
 \Cref{sec:classy_reprise} shows how the boilerplate can be minimised using advanced type system extensions.
 
 \section*{Acknowledgements}
@@ -749,12 +749,12 @@ Furthermore, I would like to thank Pieter and Rinus for the fruitful discussions
 \label{sec:classy_reprise}
 One of the unique selling points of this novel \gls{DSL} embedding technique is that it, in its basic form, does not require advanced type system extensions nor a lot of boilerplate.
 However, generalising the technique to \glspl{GADT} arguably unleashes a cesspool of \emph{unsafe} compiler extensions.
-If we are willing to work with extensions, almost all of the boilerplate can be inferred or generated.
+If we are willing to work with extensions, almost all the boilerplate can be inferred or generated.
 
 In classy deep embedding, the \gls{DSL} datatype is parametrised by a type variable providing a witness to the interpretation on the language.
 When using multiple interpretations, these need to be bundled in a data type.
 Using the \gls{GHC}'s \GHCmod{ConstraintKind} extension, we can make these witnesses explicit, tying into \gls{HASKELL}'s type system immediately.
-Furthermore, this constraint does not necessarily has to be a single constraint, after enabling \GHCmod{DataKinds} and \GHCmod{TypeOperators}, we can encode lists of witnesses instead \citep{yorgey_giving_2012}.
+Furthermore, this constraint does not necessarily have to be a single constraint, after enabling \GHCmod{DataKinds} and \GHCmod{TypeOperators}, we can encode lists of witnesses instead \citep{yorgey_giving_2012}.
 The data type for this list of witnesses is \haskelllhstexinline{Record} as shown in \cref{lst_cbde:record_type}.
 This \gls{GADT} is parametrised by two type variables.
 The first type variable (\haskelllhstexinline{dt}) is the type or type constructor on which the constraints can be applied and the second type variable (\haskelllhstexinline{clist}) is the list of constraints constructors itself.
@@ -837,7 +837,7 @@ e0 = neg (neg (Lit 42 `Add` (Lit 38 `subt` Lit 4)))
 \end{lstHaskellLhstex}
 
 It is also possible to define terms in the \gls{DSL} as being overloaded in the interpretation.
-This does require enumerating all the \haskelllhstexinline{CreateRecord} type classes for every extension in a similar fashion as was required for \haskelllhstexinline{GDict}.
+This does require enumerating all the \haskelllhstexinline{CreateRecord} type classes for every extension similarly as was required for \haskelllhstexinline{GDict}.
 At the call site, the concrete list of constraints must be known.
 
 \begin{lstHaskellLhstex}
index 94b5704..da783ac 100644 (file)
@@ -43,8 +43,8 @@ Concretely, it is not possible to
 \end{enumerate*}
 The functions for this are simply not available automatically in the embedded language.
 For some semantics---such as an interpreter---it is possible to directly lift the functions from the host language to the \gls{DSL}.
-In other cases---e.g.\ \emph{compiling} \glspl{DSL} such as a compiler or a printer---this is not possible \citep{elliott_compiling_2003}. %the torget this is not possible. cannot just be lifted from the host language to the \gls{DSL} so it requires a lot of boilerplate to define and implement them.
-Thus, all of the operations on the data type have to be defined by hand requiring a lot of plumbing and resulting in a lot of boilerplate code.
+In other cases---e.g.\ \emph{compiling} \glspl{DSL} such as a compiler or a printer---this is not possible \citep{elliott_compiling_2003}. %the torget this is not possible. Cannot just be lifted from the host language to the \gls{DSL} so it requires a lot of boilerplate to define and implement them.
+Thus, all the operations on the data type have to be defined by hand requiring a lot of plumbing and resulting in a lot of boilerplate code.
 
 To relieve the burden of adding all these functions, metaprogramming\nobreak---\nobreak\hskip0pt and custom quasiquoters---can be used.
 Metaprogramming entails that some parts of the program are generated by a program itself, i.e.\ the program is data.
@@ -120,7 +120,7 @@ First a data type representing the semantics is defined. In this case, the print
        \haskellinline{newtype}s are special data types only consisting a single constructor with one field to which the type is isomorphic.
        During compilation the constructor is completely removed resulting in no overhead \citep[\citesection{4.2.3}]{peyton_jones_haskell_2003}.
 }
-Since the language is typed, the printer data type has to have a type variable but it is only used during typing---i.e.\ a phantom type \citep{leijen_domain_2000}:
+Since the language is typed, the printer data type has to have a type variable, but it is only used during typing---i.e.\ a phantom type \citep{leijen_domain_2000}:
 
 \begin{lstHaskell}
 newtype Printer a = P { runPrinter :: String }
@@ -142,7 +142,7 @@ instance Div Printer where
 \subsection{Functions}
 Adding functions to the language is achieved by adding a multi-parameter class to the \gls{DSL}.
 The type of the class function allows for the implementation to only allow first-order functions by supplying the arguments in a tuple.
-Furthermore, with the \haskellinline{:-} operator the syntax becomes usable.
+Furthermore, with the \haskellinline{:-} operator the syntax becomes useable.
 Finally, by defining the functions as a \gls{HOAS} type safety is achieved \citep{pfenning_higher-order_1988,chlipala_parametric_2008}.
 The complete definition looks as follows:
 
@@ -153,7 +153,7 @@ data In a b = a :- b
 infix 1 :-
 \end{lstHaskell}
 
-The \haskellinline{Function} type class is now used to define functions with little syntactic overhead\footnote{The \GHCmod{BlockArguments} extension of GHC is used to reduce the number of brackets that allows lambda's to be an argument to a function without brackets}.
+The \haskellinline{Function} type class is now used to define functions with little syntactic overhead\footnote{The \GHCmod{BlockArguments} extension of \gls{GHC} is used to reduce the number of brackets that allows lambda's to be an argument to a function without brackets}.
 The following listing shows an expression in the \gls{DSL} utilising two user-defined functions:
 
 \begin{lstHaskell}
@@ -206,7 +206,7 @@ in f0 (f2 38 5)
 Lifting values from the host language to the \gls{DSL} is possible using the \haskellinline{lit} function as long as the type of the value has instances for all the class constraints.
 Unfortunately, once lifted, it is not possible to do anything with values of the user-defined data type other than passing them around.
 It is not possible to construct new values from expressions in the \gls{DSL}, to deconstruct a value into the fields, nor to test of which constructor the value is.
-Furthermore, while in the our language the only constraint is the automatically derivable \haskellinline{Show}, in real-world languages the class constraints may be very difficult to satisfy for complex types, for example serialisation to a single stack cell in the case of a compiler.
+Furthermore, while in our language the only constraint is the automatically derivable \haskellinline{Show}, in real-world languages the class constraints may be very difficult to satisfy for complex types, for example serialisation to a single stack cell in the case of a compiler.
 
 As a consequence, for user-defined data types---such as a pro\-gram\-mer-defined list type\footnotemark---to become first-class citizens in the \gls{DSL}, language constructs for constructors, deconstructors and constructor predicates must be defined.
 Field selectors are also useful functions for working with user-defined data types, they are not considered for the sake of brevity but can be implemented using the deconstructor functions.
@@ -231,7 +231,7 @@ class ListDSL v where
 Furthermore, instances for the \gls{DSL}'s views need to be created.
 For example, to use the interpreter, the following instance must be available.
 Note that at first glance, it would feel natural to have \haskellinline{isNil} and \haskellinline{isCons} return \haskellinline{Nothing} since we are in the \haskellinline{Maybe} monad.
-However, the this would fail the entire expression and the idea is that the constructor test can be done from within the \gls{DSL}.
+However, this would fail the entire expression and the idea is that the constructor test can be done from within the \gls{DSL}.
 
 \begin{lstHaskell}
 instance ListDSL Maybe where
@@ -267,7 +267,7 @@ These functions are monadic functions operating in the \haskellinline{Q} monad.
 The \haskellinline{Q} monad facilitates failure, reification and fresh identifier generation for hygienic macros \citep{kohlbecker_hygienic_1986}.
 Within the \haskellinline{Q} monad, capturable and non-capturable identifiers can be generated using the \haskellinline{mkName} and \haskellinline{newName} functions respectively.
 The \emph{Peter Parker principle}\footnote{With great power comes great responsibility.} holds for the \haskellinline{Q} monad as well because it executes at compile time and is very powerful.
-For example it can subvert module boundaries, thus accessing constructors that were hidden; access the structure of abstract types; and it may cause side effects during compilation because it is possible to call \haskellinline{IO} operations \citep{terei_safe_2012}.
+For example, it can subvert module boundaries, thus accessing constructors that were hidden; access the structure of abstract types; and it may cause side effects during compilation because it is possible to call \haskellinline{IO} operations \citep{terei_safe_2012}.
 To achieve the goal of embedding data types in a \gls{DSL} we refrain from using these \emph{unsafe} features.
 
 \subsection{Data types}
@@ -550,7 +550,7 @@ mkPrinter = instanceD (cxt []) [t|$(conT (className typeName)) Printer|]
 \end{lstHaskell}
 
 To be able to define a printer that is somewhat more powerful, we provide instances for \haskellinline{MonadWriter}; add a state for fresh variables and a context; and define some helper functions the \haskellinline{Printer} datatype.
-The \haskellinline{printLit} function is a variant of \haskellinline{MonadWriter}s \haskellinline{tell} that prints a literal string but it can be of any type (it is a phantom type anyway).
+The \haskellinline{printLit} function is a variant of \haskellinline{MonadWriter}s \haskellinline{tell} that prints a literal string, but it can be of any type (it is a phantom type anyway).
 \haskellinline{printCons} prints a constructor name followed by an expression, it inserts parenthesis only when required depending on the state.
 \haskellinline{paren} always prints parenthesis around the given printer.
 \haskellinline{>->} is a variant of the sequence operator \haskellinline{>>} from the \haskellinline{Monad} class, it prints whitespace in between the arguments.
@@ -695,7 +695,7 @@ bin = QuasiQuoter { quoteExp = parseBin }
 Custom quasiquoters allow the \gls{DSL} user to enter fragments verbatim, bypassing the syntax of the host language.
 Pattern matching in general is not suitable for a custom quasiquoter because it does not really fit in one of the four syntactic categories for which custom quasiquoter support is available.
 However, a concrete use of pattern matching, interesting enough to be beneficial, but simple enough for a demonstration is the \emph{simple case expression}, a case expression that does not contain nested patterns and is always exhaustive.
-They correspond to multi-way conditional expressions and can thus be converted to \gls{DSL} constructs straightforwardly \citep[\citesection{4.4}]{peyton_jones_implementation_1987}.
+They correspond to multi-way conditional expressions and can thus be converted to \gls{DSL} constructs straightforwardly \citep[\citesection{4.4}]{peyton_jones_implementation_1987}.
 
 In contrast to the binary literal quasiquoter example, we do not create the parser by hand.
 The parser combinator library \emph{parsec} is used instead to ease the creation of the parser \citep{leijen_parsec_2001}.
@@ -796,7 +796,7 @@ The main difference with this work is that it requires a compiler plugin while o
 \subsection{Related work on Template Haskell}
 Metaprogramming in general is a very broad research topic and has been around for years already.
 We therefore do not claim an exhaustive overview of related work on all aspects of metaprogramming.
-However, we have have tried to present most research on metaprogramming in \gls{TH}.
+However, we have tried to present most research on metaprogramming in \gls{TH}.
 \Citet{czarnecki_dsl_2004} provide a more detailed comparison of different metaprogramming techniques.
 They compare staged interpreters, metaprogramming and templating by comparing MetaOCaml, \gls{TH} and \gls{CPP} templates.
 \gls{TH} has been used to implement related work.
@@ -819,7 +819,7 @@ In similar fashion, \citet{materzok_generating_2022} used \gls{TH} to translate
 
 \subsubsection{Optimisation}
 Besides generating code, it is also possible to analyse existing code and perform optimisations.
-Yet, this is dangerous territory because unwantedly the semantics of the optimised program may be slightly different from the original program.
+Yet, this is dangerous territory because unwantedly, the semantics of the optimised program may be slightly different from the original program.
 For example, \citet{lynagh_unrolling_2003} implemented various optimisations in \gls{TH} such as automatic loop unrolling.
 The compile-time executed functions analyse the recursive function and unroll the recursion to a fixed depth to trade execution speed for program space.
 Also, \citet{odonnell_embedding_2004} embedded Hydra, a hardware description language, in \gls{HASKELL} utilising \gls{TH}.
diff --git a/glossary.bash b/glossary.bash
new file mode 100644 (file)
index 0000000..5805ebe
--- /dev/null
@@ -0,0 +1,11 @@
+#!/bin/bash
+
+entries () {
+       grep -Po "(newglossaryentry|new(abbreviation|acronym)(\[.*\])?)\{[A-Z0-9]+" "$1" | grep -Po "[A-Z0-9]+$"
+}
+
+# find number of occurances
+entries preamble/glossaries.tex | xargs -I'<>' bash -c 'echo -n "<> " && grep -ni --color=always "{<>}" {appx,front,back,intro,concl,top,tvt,dsl}/*.tex | wc -l' | sort -nk2
+
+# find uses without \gls*{}
+#entries preamble/glossaries.tex | xargs -I'<>' grep -nPi --color=always "[ ]<>[. $]" {appx,front,back,intro,concl,top}/*.tex
index 42313f5..8ecfbd0 100644 (file)
 
 There are at least 13.4 billion devices connected to the internet at the time of writing \citep{transforma_insights_current_2023}.
 Each of these devices sense, act, or otherwise, interact with people, computers, and the environment.
-Despite their immense diversity, they are all computers and they they all require software to operate.
+Despite their immense diversity, they are all computers and they all require software to operate.
 
 An increasing number of these connected devices are so-called edge devices that operate in the \gls{IOT}.
 Edge devices are the leaves of the \gls{IOT} systems.
 They perform the interaction with the physical world.
 It is not uncommon for edge devices to be physically embedded in the fabric itself.
-Typically they reside in hard-to-reach places such as light bulbs, clothing, smart electricity meters, buildings, or even farm animals.
+Typically, they reside in hard-to-reach places such as light bulbs, clothing, smart electricity meters, buildings, or even farm animals.
 The majority of edge devices are powered by microcontrollers.
 Microcontrollers are equipped with a lot of connectivity for integrating peripherals such as sensors and actuators.
 The connectivity makes them very suitable to interact with their surroundings.
@@ -66,7 +66,7 @@ The \citet{wikipedia_contributors_rhapsody_2022} define a musical rhapsody is de
 \end{quote}
 This dissertation consists of three episodes.
 \Cref{prt:dsl} is a paper-based---otherwise known as cumulative---episode containing chapters that provide insight in advanced \gls{DSL} embedding techniques for \gls{FP} languages.
-The chapters can be read independently from each other.
+The chapters can be read independently of each other.
 \Cref{prt:top} is a monograph showing \gls{MTASK}, a \gls{TOP} \gls{DSL} for the \gls{IOT}.
 Hence, the chapters in this episode are best read in order.
 It introduces \gls{IOT} edge device programming, shows the complete \gls{MTASK} language, provides details on how \gls{MTASK} is integrated with \gls{ITASK}, shows how the byte code compiler is implemented, presents a guide for green computing with \gls{MTASK}, and ends with a conclusion and overview of future and related work.
@@ -413,11 +413,11 @@ It is compiled from the following publications:
 %              \paragraph{Contribution}
 %              The research in this paper and writing the paper was performed by me, though there were weekly meetings with Pieter Koopman and Rinus Plasmeijer.
        \item \emph{Simulation of a Task-\kern-1.25ptBased Embedded Domain Specific Language for the Internet of Things} \citep*{koopman_simulation_2023}\footnotemark[\value{footnote}]
-               are the revised lecture notes for a course on the \gls{MTASK} simulator provided at the 2018 \gls{CEFP}\slash{}\gls{3COWS} winter school in Ko\v{s}ice, Slovakia, January 22--26, 2018.
+               are the revised lecture notes for a course on the \gls{MTASK} simulator provided at the 2018 \gls{3COWS} winter school in Ko\v{s}ice, Slovakia, January 22--26, 2018.
 %              \paragraph{Contribution}
 %              Pieter Koopman wrote and taught it, I helped with the software and research.
        \item \emph{Writing Internet of Things Applications with Task Oriented Programming} \citep*{lubbers_writing_2023}\footnotemark[\value{footnote}]
-               are the revised lecture notes from a course on programming \gls{IOT} systems using \gls{MTASK} provided at the 2019 \gls{CEFP}\slash{}\gls{3COWS} summer school in Budapest, Hungary, June 17--21, 2019.
+               are the revised lecture notes from a course on programming \gls{IOT} systems using \gls{MTASK} provided at the 2019 \gls{3COWS} summer school in Budapest, Hungary, June 17--21, 2019.
 %              \paragraph{Contribution}
 %              Pieter Koopman prepared and taught half of the lecture and supervised the practical session.
 %              I taught the other half of the lecture, wrote the lecture notes, made the assignments and supervised the practical session.
index 6c99494..66ea5c5 100644 (file)
@@ -9,7 +9,7 @@
 \GlsXtrEnableInitialTagging{acronym,abbreviation}{\itag}
 
 \newcommand*{\glsxtrpostnameacronym}{%
-       \space\rm\glsentrylong{\glscurrententrylabel}%
+       \space\rm\glsentrylong{\glscurrententrylabel}%
 }
 %\renewcommand*{\glsxtrpostdescabbreviation}{%
 % \space (initialism)%
@@ -36,7 +36,6 @@
 \makeglossaries%
 
 % Acronyms
-\newacronym[description={the CO\textsubscript{2} concentration calculated from \glsxtrshort{TVOC} measurements}]{ECO2}{(eCO\textsubscript{2})}{equivalent carbon dioxide}
 \newacronym[description={a open data interchange format using human readable text}]{JSON}{JSON}{(JavaScript object notation)}
 \newacronym[description={a publish-subscribe network protocol designed for resource constrained devices}]{MQTT}{MQTT}{(MQ telemetry transport)}
 \newacronym[description={a pure lazy \glsxtrlong{FP} language based on graph rewriting}]{CLEAN}{Clean}{(Clean language of East-Anglia and Nijmegen)}
@@ -51,7 +50,6 @@
 \newabbreviation{AST}{AST}{abstract syntax tree}
 \newabbreviation{API}{API}{application programming interface}
 \newabbreviation{ARDSL}{ARDSL}{\gls{ARDUINO} \glsxtrshort{DSL}}
-\newabbreviation[category=noexpand]{CEFP}{CEFP}{Central European \glsxtrlong{FP} School}
 \newabbreviation{CRS}{CRS}{\gls{CLEAN} Raspberry Pi system}
 \newabbreviation{CRTS}{CRTS}{\gls{CLEAN} Raspberry Pi temperature sensor}
 \newabbreviation{CWS}{CWS}{\gls{CLEAN} \gls{WEMOS} system}
@@ -78,7 +76,6 @@
 \newabbreviation[category=noexpand,prefixfirst={a\ },prefix={an\ }]{LED}{LED}{light-emitting diode}
 \newabbreviation[category=noexpand]{OLED}{OLED}{organic \glsxtrshort{LED}}
 \newabbreviation[category=noexpand]{OS}{OS}{operating system}
-\newabbreviation{OTA}{OTA}{over-the-air}
 \newabbreviation{PFRP}{p-frp}{priority-based \glsxtrshort{FRP}}
 \newabbreviation{PRS}{PRS}{\gls{PYTHON} Raspberry Pi system}
 \newabbreviation{PWS}{PWS}{\gls{MICROPYTHON} \gls{WEMOS} system}
@@ -96,7 +93,6 @@
 \newabbreviation{TH}{TH}{Template \gls{HASKELL}}
 \newabbreviation[category=noexpand]{TCP}{TCP}{transmission control protocol}
 \newabbreviation{TOSD}{TOSD}{task-oriented software development}
-\newabbreviation{TRS}{TRS}{term rewriting system}
 \newabbreviation{TTH}{TTH}{typed \glsxtrlong{TH}}
 \newabbreviation{TVOC}{TVOC}{total volatile organic compounds}
 \newabbreviation{UI}{UI}{user interface}
        name=ABC,
        description={\gls{CLEAN}'s intermediate graph-rewriting language},
 }
+\newglossaryentry{ECO2}{%
+       name={eCO\textsubscript{2}},
+       description={CO\textsubscript{2} concentration calculated from \glsxtrshort{TVOC} measurements},
+}
 \newglossaryentry{MTASK}{%
        name=mTask,
        description={a \glsxtrshort{TOP} \glsxtrshort{EDSL} for edge devices integrated with the \gls{ITASK} system},
        name=Haskell,
        description={a pure lazy \glsxtrlong{FP} language designed by a committe as a concept language}
 }
-\newglossaryentry{HASKELL98}{%
-       name=Haskell98,
-       description={a standardised version of \gls{HASKELL}},
-}
 \newglossaryentry{ARDUINO}{%
        name=Arduino,
        description={a widely used framework for programming microcontrollers}
 }
-\newglossaryentry{MBED}{%
-       name=mbed,
-       description={a widely used framework for programming microcontrollers designed for ARM cortex-M}
-}
 \newglossaryentry{CPP}{
        name=C\texttt{++},
        description={a general-purpose imperative programming language based on \gls{C}}
        name=Wi-Fi,
        description={is a family of wireless network protocols commonly used for local area networking}
 }
-\newglossaryentry{TINYML}{
-       name=TinyML,
-       description={a deep learning framework for microcontrollers}
-}
 \newglossaryentry{PYTHON}{
        name=Python,
        description={a multi-paradigm interpreted programming language}
        name=MicroPython,
        description={a \gls{PYTHON} implementation tailored for microcontrollers}
 }
-\newglossaryentry{FREERTOS}{
-       name=FreeRTOS,
-       description={an open-source \glsxtrshort{RTOS} for microcontrollers}
-}
 \newglossaryentry{ONEWIRE}{
        name=1-wire,
        description={a simple single wire communication protocol often used to connect sensors to microcontrollers}
index 9a89319..b864f14 100644 (file)
@@ -24,7 +24,7 @@ They differ significantly from regular computers in many aspects, and as a conse
 For example, they are much smaller; only have a fraction of the memory and processor speed; and run on different architectures.
 Furthermore, they have much more energy-efficient sleep modes, and support connecting and interfacing with peripherals such as sensors and actuators.
 To illustrate the difference in characteristics, \cref{tbl:mcu_laptop} compares the hardware properties of a typical laptop with two popular microcontrollers.
-Usually, programming microcontrollers requires an elaborate multi-step toolchain of compilation, linkage, binary image creation, and burning this image onto the flash memory of the microcontroller in order to run a program.
+Usually, programming microcontrollers requires an elaborate multistep toolchain of compilation, linkage, binary image creation, and burning this image onto the flash memory of the microcontroller in order to run a program.
 The software is usually a cyclic executive instead of tasks that run in an \gls{OS}.
 Hence, all tasks must be manually combined into a single program.
 
@@ -51,7 +51,7 @@ Hence, all tasks must be manually combined into a single program.
 All microcontroller models require their own vendor-provided drivers, hardware abstraction layer, compilers and \glspl{RTS}.
 To structure this jungle of tools, platforms exist that provide an abstraction layer over the low-level toolchains.
 An example of this is the \gls{ARDUINO} environment\footnote{\refurl{https://www.arduino.cc}{\formatdate{19}{12}{2022}}}.
-Originally it was designed for the in-house developed open-source hardware with the same name but the setup allows porting to many architectures by vendor-provided \emph{cores}.
+Originally it was designed for the in-house developed open-source hardware with the same name, but the setup allows porting to many architectures by vendor-provided \emph{cores}.
 This set of tools is specifically designed for education and prototyping and hence used here to illustrate traditional microcontroller programming.
 It consists of an \gls{IDE} containing toolchain automation, a dialect of \ccpp{}, and libraries providing an abstraction layer for microcontroller behaviour.
 With \gls{ARDUINO}, the programmer can program multiple types of microcontrollers using a single language.
@@ -68,7 +68,7 @@ Edge devices in \gls{IOT} systems are typically slow but energy efficient and do
 The \gls{MTASK} system bridges this gap by providing a domain-specific \gls{TOP} language for \gls{IOT} edge devices.
 Domain-specific knowledge is embedded in the language and execution platform and unnecessary features for edge devices are removed to drastically lower the hardware requirements.
 Programs in \gls{MTASK} are written in the \gls{MTASK} \gls{DSL}, a \gls{TOP} language that offers a similar abstraction level as \gls{ITASK}.
-Tasks in \gls{MTASK} operate as if they are \gls{ITASK} tasks, their task value is observable by other tasks and they can share data using \gls{ITASK} \glspl{SDS}.
+Tasks in \gls{MTASK} operate as if they are \gls{ITASK} tasks, their task value is observable by other tasks, and they can share data using \gls{ITASK} \glspl{SDS}.
 This allows for programming entire \gls{IOT} systems from a single abstraction level, source code, and programming paradigm.
 
 \section{Hello world!}
@@ -164,7 +164,7 @@ Furthermore, the \arduinoinline{delay} function can not be used and polling \ard
 The \arduinoinline{millis} function returns the number of milliseconds that have passed since the boot of the microcontroller.
 If the delay passed to the \arduinoinline{delay} function is long enough, the firmware may decide to put the processor in sleep mode, reducing the power consumption drastically.
 When polling \arduinoinline{millis} is used, this therefore potentially affects power consumption since the processor is busy looping all the time, not knowing when to go to sleep.
-Manually combining tasks into a single modular program is very error prone, requires a lot of pointer juggling, and generally results into spaghetti code.
+Manually combining tasks into a single modular program is very error-prone, requires a lot of pointer juggling, and generally results into spaghetti code.
 Furthermore, it is very difficult to represent dependencies between threads.
 Often state machines have to be explicitly programmed and merged by hand to achieve this.
 In the simple case of blinking three \glspl{LED} according to fixed intervals, it is possible to calculate the delays in advance using static analysis and generate the appropriate \arduinoinline{delay} calls.
@@ -216,7 +216,7 @@ This chapter introduced traditional edge device programming and programming edge
 The edge layer of \gls{IOT} systems is powered by microcontrollers.
 Microcontrollers have significantly different characteristics to regular computers.
 Programming them happens through compiled firmwares using low-level imperative programming languages.
-Due to the lack of an \gls{OS}, writing applications that perform multiple tasks at the same time is error prone, becomes complex, and requires a lot of boilerplate such as manual scheduling code.
+Due to the lack of an \gls{OS}, writing applications that perform multiple tasks at the same time is error-prone, becomes complex, and requires a lot of boilerplate such as manual scheduling code.
 With the \gls{MTASK} system, a \gls{TOP} programming language for \gls{IOT} edge devices, this limitation can be overcome.
 Since much domain-specific knowledge is built into the language and \gls{RTS}, the hardware requirements can be kept relatively low while maintaining a high abstraction level.
 Furthermore, the programs are automatically integrated with \gls{ITASK}, a \gls{TOP} system for creating interactive distributed web applications, allowing for data sharing, task coordination, and dynamic construction of tasks.
index 397caf4..6b002bb 100644 (file)
@@ -42,7 +42,7 @@ Furthermore, \gls{ITASK} \glspl{SDS} can be lowered to \gls{MTASK} tasks as well
 
 \section{Related work}
 The novelties of the \gls{MTASK} system can be compared to existing systems in several categories.
-It is a interpreted (\cref{sec:related_int}) \gls{TOP} (\cref{sec:related_top}) \gls{DSL} (\cref{sec:related_dsl}) that may seem similar at first glance to \gls{FRP} (\cref{sec:related_frp}), it is implemented in a functional language (\cref{sec:related_fp}) and due to the execution semantics, multitasking is automatically supported (\cref{sec:related_multi}).
+It is an interpreted (\cref{sec:related_int}) \gls{TOP} (\cref{sec:related_top}) \gls{DSL} (\cref{sec:related_dsl}) that may seem similar at first glance to \gls{FRP} (\cref{sec:related_frp}), it is implemented in a functional language (\cref{sec:related_fp}) and due to the execution semantics, multitasking is automatically supported (\cref{sec:related_multi}).
 \Cref{sec_t4t:TiredvsTierless} contains an elaborate related work section regarding tierless systems in general.
 
 \subsection{Interpretation}\label{sec:related_int}
@@ -68,7 +68,7 @@ Both imperative \glspl{DSL} embedded in a functional language that compile to \c
 \subsection{Functional programming}\label{sec:related_fp}
 \Citet{haenisch_case_2016} showed that there are major benefits to using functional languages on edge devices.
 They show that using function languages increased the security and maintainability of the applications.
-Traditional implementations of general purpose functional languages have high memory requirements rendering them unusable for resource-constrained computers.
+Traditional implementations of general purpose functional languages have high memory requirements rendering them unuseable for resource-constrained computers.
 There have been many efforts to create a general purpose functional language that does fit in small memory environments, albeit with some concessions.
 For example, there has been a history of creating tiny Scheme implementations for specific microcontrollers.
 It started with BIT \citep{dube_bit:_2000} that only required \qty{64}{\kibi\byte} of memory, followed by {PICBIT} \citep{feeley_picbit:_2003} and {PICOBIT} \citep{st-amour_picobit:_2009} that lowered the memory requirements even more.
@@ -81,7 +81,7 @@ An interpreted Lisp implementation called uLisp also exists that runs on microco
 Applications for tiny computers are often parallel in nature.
 Tasks like reading sensors, watching input devices, operating actuators and maintaining communication are often loosely dependent on each other and are preferably executed in parallel.
 Microcontrollers often do not benefit from an \gls{OS} due to memory and processing constraints.
-Therefore, writing multitasking applications in an imperative language is possible but the tasks have to be interleaved by hand \citep{feijs_multi-tasking_2013}.
+Therefore, writing multitasking applications in an imperative language is possible, but the tasks have to be interleaved by hand \citep{feijs_multi-tasking_2013}.
 This results in hard to maintain, error-prone and unscalable spaghetti code.
 
 There are many solutions to overcome this problem in imperative languages.
@@ -163,7 +163,7 @@ Other examples are CFRP \citep{suzuki_cfrp_2017}, XFRP \citep{10.1145/3281366.32
 \Gls{TOP} as a paradigm has proven to be effective for implementing distributed, multi-user applications in many domains.
 Examples are conference management \citep{plasmeijer_conference_2006}, coastal protection \citep{lijnse_capturing_2011}, incident coordination \citep{lijnse_incidone:_2012}, crisis management \citep{jansen_towards_2010} and telemedicine \citep{van_der_heijden_managing_2011}.
 In general, \gls{TOP} results in a higher maintainability, a high separation of concerns, and more effective handling of interruptions of workflow.
-\Gls{IOT} applications contain a distributed and multi-user component, but the software on the device is mostly follows multiple loosely dependent workflows.
+\Gls{IOT} applications contain a distributed and multi-user component, but the software on the device mostly follows multiple loosely dependent workflows.
 The only other \gls{TOP} language for embedded systems is $\mu$Tasks \citep{piers_task-oriented_2016}.
 It is a non-distributed \gls{TOP} \gls{EDSL} hosted in \gls{HASKELL} designed for embedded systems such as payment terminals.
 They show that applications tend to be able to cope well with interruptions and are more maintainable.
@@ -198,7 +198,7 @@ Instead of equipping the edge device with a battery, a capacitor is used in conj
 After a reset, the program state is resumed from a checkpoint that was stored in some non-volatile memory.
 This technique is called intermittent computing \citep{hester_batteries_2019}.
 Many intermittent computing solutions rely on annotations from the programmer to divide the program into atomic blocks, sometimes called tasks as well.
-These blocks are marked as such, because in the case of an reset of the system, the work must be done again.
+These blocks are marked as such, because in the case of a reset of the system, the work must be done again.
 Examples of such blocks are \gls{I2C} transmissions or calculations that rely on recent sensor data.
 In \gls{MTASK}, all work expressed by tasks is already split up in atomic pieces of work, i.e.\ the work is a side effect of rewriting.
 Furthermore, creating checkpoints should be fairly straightforward as \gls{MTASK} tasks do not rely on any global state---all information required to execute a task is stored in the task tree.
@@ -266,7 +266,7 @@ However, it should be possible to make abstractions over an increasing number of
 For example, the pin mode could be made a type parameter of the \gls{GPIO} pins, or interrupt handling could be made safer by incorporating the capabilities of the devices in order to reduce run-time errors.
 
 \subsection{Scheduling}
-The scheduling in \gls{MTASK} works quite well but it is not real time.
+The scheduling in \gls{MTASK} works quite well, but it is not real time.
 There is a variant of \gls{FRP} called \gls{PFRP} that allows for real-time operation \citep{belwal_variable_2013}.
 Furthermore, an alternative to reducing the energy consumption by going to sleep is stepping down the processor frequency.
 So called \gls{DVFS} is a scheduling technique that slows down the processor in order to reach the goals as late as possible, reducing the power consumption.
@@ -283,7 +283,7 @@ A first throw at a class-based shallowly \gls{EDSL} for microcontrollers was mad
 The language was called \gls{ARDSL} and offered a type safe interface to \gls{ARDUINO} \gls{CPP} dialect.
 A \gls{CPP} code generation interpretation was available together with an \gls{ITASK} simulation interpretation.
 There was no support for tasks nor functions.
-Some time later in the 2015 \gls{CEFP} summer school, an extended version was created that allowed the creation of imperative tasks, local \glspl{SDS} and the usage of functions \citep{koopman_type-safe_2019}.
+Some time later in the 2015 CEFP summer school, an extended version was created that allowed the creation of imperative tasks, local \glspl{SDS} and the usage of functions \citep{koopman_type-safe_2019}.
 The name then changed from \gls{ARDSL} to \gls{MTASK}.
 
 \subsection{Integration with iTask}
@@ -293,7 +293,7 @@ In this way, entire \gls{IOT} systems could be programmed from a single source.
 However, this version used a simplified version of \gls{MTASK} without functions.
 This was later improved upon by creating a simplified interface where \glspl{SDS} from \gls{ITASK} could be used in \gls{MTASK} and the other way around \citep{lubbers_task_2018}.
 It was shown by \citet{amazonas_cabral_de_andrade_developing_2018} that it was possible to build real-life \gls{IOT} systems with this integration.
-Moreover, a course on the \gls{MTASK} simulator was provided at the 2018 \gls{CEFP}\slash\gls{3COWS} winter school in Ko\v{s}ice, Slovakia \citep{koopman_simulation_2023}.
+Moreover, a course on the \gls{MTASK} simulator was provided at the 2018 \gls{3COWS} winter school in Ko\v{s}ice, Slovakia \citep{koopman_simulation_2023}.
 
 \subsection{Transition to Task-oriented programming}
 The \gls{MTASK} language as it is now was introduced in 2018 \citep{koopman_task-based_2018}.
@@ -301,7 +301,7 @@ This paper updated the language to support functions, simple tasks, and \glspl{S
 Later the byte code compiler and \gls{ITASK} integration was added to the language \citep{lubbers_interpreting_2019}.
 Moreover, it was shown that it is very intuitive to write microcontroller applications in a \gls{TOP} language \citep{lubbers_multitasking_2019}.
 One reason for this is that a lot of design patterns that are difficult using standard means are for free in \gls{TOP} (e.g.\ multithreading).
-In 2019, the \gls{CEFP}\slash\gls{3COWS} summer school in Budapest, Hungary hosted a course on developing \gls{IOT} applications with \gls{MTASK} as well \citep{lubbers_writing_2023}.
+In 2019, the \gls{3COWS} summer school in Budapest, Hungary hosted a course on developing \gls{IOT} applications with \gls{MTASK} as well \citep{lubbers_writing_2023}.
 
 \subsection{Task-oriented programming}
 In 2022, the SusTrainable summer school in Rijeka, Croatia hosted a course on developing greener \gls{IOT} applications using \gls{MTASK} \citep{lubbers_green_2022}.
@@ -313,7 +313,7 @@ In 2023, the SusTrainable summer school in Coimbra, Portugal will host a course
 Funded by the Radboud-Glasgow Collaboration Fund, collaborative work was executed with Phil Trinder, Jeremy Singer, and Adrian Ravi Kishore Ramsingh.
 An existing smart campus application was developed using \gls{MTASK} and quantitatively and qualitatively compared to the original application that was developed using a traditional \gls{IOT} stack \citep{lubbers_tiered_2020}.
 This research was later extended to include a four-way comparison: \gls{PYTHON}, \gls{MICROPYTHON}, \gls{ITASK}, and \gls{MTASK} \citep{lubbers_could_2022}.
-Currently, power efficiency behaviour of traditional versus \gls{TOP} \gls{IOT} stacks is being compared as well adding a \gls{FREERTOS}, and an Elixir implementation to the mix as well.
+Currently, power efficiency behaviour of traditional versus \gls{TOP} \gls{IOT} stacks is being compared as well adding a FreeRTOS, and an Elixir implementation to the mix as well.
 
 \input{subfilepostamble}
 \end{document}
index 1670a2a..f228ab1 100644 (file)
@@ -9,7 +9,7 @@
 \chapter{Green computing with mTask}%
 \label{chp:green_computing_mtask}
 \begin{chapterabstract}
-       This chapter demonstrate the energy-saving features of \gls{MTASK} by:
+       This chapter demonstrates the energy-saving features of \gls{MTASK} by:
        \begin{itemize}
                \item giving an overview of general green computing measures for edge devices;
                \item explaining task scheduling in \gls{MTASK}, and how to tweak it so suit the applications and energy needs;
@@ -26,7 +26,7 @@ To reduce the power consumption of an \gls{IOT} edge device, the specialised low
 Different sleep mode achieve different power reductions because of their run time characteristics.
 These specifics range from disabling or suspending the \gls{WIFI} radio; stop powering (parts) of the \gls{RAM}; disabling peripherals; or even turning off the processor completely, requiring an external signal to wake up again.
 Determining exactly when, and for how long it is safe to sleep is expensive in the general case.
-In practise it means that either annotations in the source code, a \gls{RTOS}, or a scheduler is required.
+In practise, it means that either annotations in the source code, a \gls{RTOS}, or a scheduler is required.
 
 \Cref{tbl:top_sleep} shows the properties and current consumption of two commonly used microcontrollers in their various sleep modes.
 It uncovers that switching the \gls{WIFI} radio off yields the biggest energy saving.
@@ -84,9 +84,9 @@ Atomic blocks, such as \gls{IO}, are always contained within a rewrite step.
 This is very convenient, since the system can inspect the current state of all \gls{MTASK} expressions after a rewrite and decide if sleeping and how long is possible.
 After each loop, the \gls{RTS} knows which task is waiting on which triggers and is thus determines when it is possible and safe to sleep and choose the optimal sleep mode according to the sleeping time.
 %As a consequence, we cannot have fair multitasking.
-%When a single rewrite step would take forever due to an infinite sequence of function calls, this would block the entire IoT node.
+%When a single rewrite step would take forever due to an infinite sequence of function calls, this would block the entire \gls{IOT} node.
 %Even infinite sequences rewrite steps are perfectly fine.
-%The \gls{MTASK} system does proper tail-call optimizations to facilitate this.
+%The \gls{MTASK} system does proper tail-call optimisations to facilitate this.
 
 \section{Rewrite interval}
 Some \gls{MTASK} programs contain one or more explicit \cleaninline{delay} primitives, offering a natural place a pause.
@@ -198,7 +198,7 @@ Evaluating a task earlier should not change its result but just consumes more en
 \end{equ}
 
 \subsubsection{Sequential combinators}
-For the step combinator (\cref{R:step})---and all other derived sequential combinators\nobreak---\nobreak\hskip0ptthe refresh rate of the left-hand side task is taken since that is the only task that is rewritten during evaluaton.
+For the step combinator (\cref{R:step})---and all other derived sequential combinators\nobreak---\nobreak\hskip0ptthe refresh rate of the left-hand side task is taken since that is the only task that is rewritten during evaluation.
 Only after stepping, the combinator rewrites to the result of evaluating the right-hand side expression.
 
 \subsubsection{Repeating combinators}
@@ -262,7 +262,7 @@ rpeat ( temperature dht >>~. \temp.
 
 \subsection{Tweaking rewrite rates}
 A tailor-made \gls{ADT} (see \cref{lst:interval}) is used to tweak the timing intervals.
-The value is determined at runtime but the constructor is known at compile time.
+The value is determined at runtime, but the constructor is known at compile time.
 During compilation, the constructor of the \gls{ADT} is checked and code is generated accordingly.
 If it is \cleaninline{Default}, no extra code is generated.
 In the other cases, code is generated to wrap the task tree node in a \emph{tune rate} node.
@@ -358,7 +358,7 @@ timedPulseNaive = declarePin D0 PMOutput \d0->
 The rewrite rates from the previous section only tell us how much the next evaluation of the task can be delayed.
 In the \gls{MTASK} system, an \gls{IOT} edge devices can run multiple tasks.
 In addition, it has to communicate with a server to collect new tasks and updates of \glspl{SDS}.
-Hence, the rewrite intervals cannot be used directly to let the microcontroller sleep so a scheduler is involved.
+Hence, the rewrite intervals cannot be used directly to let the microcontroller sleep, so a scheduler is involved.
 Our scheduler has the following objectives.
 
 \begin{itemize}
@@ -405,14 +405,14 @@ The tasks are stored in a priority queue to check efficiently which of them need
 The \gls{MTASK} tasks are ordered at their absolute latest start time in this queue; earliest deadline first.
 We use the earliest deadline to order tasks with equal latest deadline.
 
-It is very complicated to make an optimal scheduling algorithm for tasks to minimize the energy consumption.
+It is very complicated to make an optimal scheduling algorithm for tasks to minimise the energy consumption.
 We use a simple heuristic to evaluate tasks and determine sleep time rather than wasting energy on a fancy evaluation algorithm.
 \Cref{lst:evalutionRound} gives this algorithm in pseudo code.
 First the edge device checks for new tasks and updates of \glspl{SDS}.
 This communication adds the new task to the queue, if there where any.
 The \cleaninline{stepped} set contains all tasks evaluated in this evaluation round.
 Next, we evaluate tasks from the queue until we encounter a task that has an evaluation interval that has not started.
-This may result in evaluating tasks earlier than required, but maximizes the opportunities to sleep after this evaluation round.
+This may result in evaluating tasks earlier than required, but maximises the opportunities to sleep after this evaluation round.
 %Using the \prog{stepped} set ensures that we evaluate each task at most once during an evaluation round.
 Executed tasks are temporarily stored in the \cleaninline{stepped} set instead of inserted directly into the queue to ensure that they are evaluated at most once in a evaluation round to ensure that there is frequent communication with the server.
 A task that produces a stable value is completed and is not queued again.
@@ -563,7 +563,7 @@ pirSwitch =
 
 While interrupt tasks have their own node type in the task tree, they differ slightly from other node types because they require a more elaborate setup and teardown.
 Enabling and disabling interrupts is done in a general way in which tasks register themselves after creation and deregister after deletion.
-Interrupts should be disabled when there are no tasks waiting for that kind of interrupt because unused interrupts can lead to unwanted wake ups, and only one kind of interrupt can be attached to a pin at the time.. 
+Interrupts should be disabled when there are no tasks waiting for that kind of interrupt because unused interrupts can lead to unwanted wake-ups, and only one kind of interrupt can be attached to a pin at the time.
 
 \subsubsection{Event registration}
 The \gls{MTASK} \gls{RTS} contains an event administration to register which task is waiting on which event.
@@ -574,7 +574,7 @@ The registration is light-weight and consists only of an event identifier and ta
 This event registration is stored as a linked list of task tree nodes so that the garbage collector cleans them up when they become unused.
 
 Registering and deregistering interrupts is a device-specific procedure, although most supported devices use the \gls{ARDUINO} \gls{API} for this.
-Which pins support which interrupt differs greatly from device to device but this information is known at compile time.
+Which pins support which interrupt differs greatly from device to device, but this information is known at compile time.
 At the time of registration, the \gls{RTS} checks whether the interrupt is valid and throws an \gls{MTASK} exception if it is not.
 Moreover, an exception is thrown if multiple types of interrupts are registered on the same pin.
 
@@ -590,7 +590,7 @@ Finally, the event is removed from the registration and the interrupt is disable
 The interrupt can be disabled as all tasks waiting for the interrupt become stable after firing.
 More occurrences of the interrupts do not change the value of the task as stable tasks keep the same value forever.
 Therefore, it is no longer necessary to keep the interrupt enabled, and it is relatively cheap to enable it again if needed in the future.
-Evaluating interrupt task node in the task tree is trivial because all of the work was already done when the interrupt was triggered.
+Evaluating interrupt task node in the task tree is trivial because all the work was already done when the interrupt was triggered.
 The task emits the status of the pin as a stable value if the information in the task shows that it was triggered.
 Otherwise, no value is emitted.
 
@@ -598,14 +598,14 @@ Otherwise, no value is emitted.
 This chapter show how we can automatically associate execution intervals to tasks.
 Based on these intervals, we can delay the executions of those tasks.
 When all task executions can be delayed, the microprocessor executing those tasks can go to sleep mode to reduce its energy consumption.
-This is a rather difficult problem that must be solved dynamically, since we make no assumptions on the number and nature of the tasks that will be allocated to an IoT node.
+This is a rather difficult problem that must be solved dynamically, since we make no assumptions on the number and nature of the tasks that will be allocated to an \gls{IOT} device.
 Furthermore, the execution intervals offer an elegant and efficient way to add interrupts to the language.
 Those interrupts offer a more elegant and energy efficient implementation of watching an input than polling this input.
 
 The actual reduction of the energy is of course highly dependent on the number and nature of the task shipped to the edge device.
 Our examples show a reduction in energy consumption of two orders of magnitude.
 Those reductions are a necessity for edge devices running of battery power.
-Given the exploding number of \gls{IOT} edge devices, such savings are also mandatory for other nodes to limit the total power consumption of the \gls{IOT}.
+Given the exploding number of \gls{IOT} edge devices, such savings are also mandatory for other devices to limit the total power consumption of the \gls{IOT}.
 
 \input{subfilepostamble}
 \end{document}
index 5d18b81..f95d69a 100644 (file)
@@ -36,7 +36,7 @@ Using small-step reduction, this task tree is continuously rewritten by the rewr
 At times, the reduction requires the evaluation of expressions, using the interpreter.
 During every rewrite step, a task value is produced.
 On the device, the \gls{RTS} may have multiple tasks at the same time active.
-By interleavig the rewrite steps, parallel operation is achieved.
+By interleaving the rewrite steps, parallel operation is achieved.
 The design, architecture and implementation of the \gls{RTS} is shown in \cref{sec:compiler_rts}.
 
 \begin{figure}
@@ -82,12 +82,12 @@ Executing the compiler is done by providing an initial state and running the mon
 After compilation, several post-processing steps are applied to make the code suitable for the microprocessor.
 First, in all tail call \cleaninline{BCReturn} instructions are replaced by \cleaninline{BCTailCall} instructions to optimise the tail calls.
 Furthermore, all byte code is concatenated, resulting in one big program.
-Many instructions have commonly used arguments so shorthands are introduced to reduce the program size.
+Many instructions have commonly used arguments, so shorthands are introduced to reduce the program size.
 For example, the \cleaninline{BCArg} instruction is often called with argument \numrange{0}{2} and can be replaced by the \numrange[parse-numbers=false]{\cleaninline{BCArg0}}{\cleaninline{BCArg2}} shorthands.
 Furthermore, redundant instructions such as pop directly after push are removed as well in order not to burden the code generation with these intricacies.
-Finally the labels are resolved to represent actual program addresses instead of the freshly generated identifiers.
+Finally, the labels are resolved to represent actual program addresses instead of the freshly generated identifiers.
 After the byte code is ready, the lowered \glspl{SDS} are resolved to provide an initial value for them.
-The byte code, \gls{SDS} specification and perpipheral specifications are the result of the process, ready to be sent to the device.
+The byte code, \gls{SDS} specification and peripheral specifications are the result of the process, ready to be sent to the device.
 
 \subsection{Instruction set}
 The instruction set is a fairly standard stack machine instruction set extended with special \gls{TOP} instructions for creating task tree nodes.
@@ -212,7 +212,7 @@ Function calls, function arguments and tasks are also compiled using $\mathcal{E
 Translating $\mathcal{E}$ to \gls{CLEAN} code is very straightforward, it basically means writing the instructions to the writer monad.
 Almost always, the type of the interpretation is not used, i.e.\ it is a phantom type.
 To still have the functions return the correct type, the \cleaninline{tell`}\footnote{\cleaninline{tell` :: [BCInstr] -> BCInterpret a}} helper is used.
-This function is similar to the writer monad's \cleaninline{tell} function but is casted to the correct type.
+This function is similar to the writer monad's \cleaninline{tell} function but is cast to the correct type.
 \Cref{lst:imp_arith} shows the implementation for the arithmetic and conditional expressions.
 Note that $r$, the context, is not an explicit argument here but stored in the state.
 
@@ -242,10 +242,10 @@ Therefore, it is just compiled using $\mathcal{E}$ with an empty context.
 \end{align*}
 
 A function call starts by pushing the stack and frame pointer, and making space for the program counter (\cref{lst:funcall_pushptrs}) followed by evaluating the arguments in reverse order (\cref{lst:funcall_args}).
-On executing \cleaninline{BCJumpSR}, the program counter is set and the interpreter jumps to the function (\cref{lst:funcall_jumpsr}).
+On executing \cleaninline{BCJumpSR}, the program counter is set, and the interpreter jumps to the function (\cref{lst:funcall_jumpsr}).
 When the function returns, the return value overwrites the old pointers and the arguments.
 This occurs right after a \cleaninline{BCReturn} (\cref{lst:funcall_ret}).
-Putting the arguments on top of pointers and not reserving space for the return value uses little space and facilitates tail call optimization.
+Putting the arguments on top of pointers and not reserving space for the return value uses little space and facilitates tail call optimisation.
 
 \begin{figure}
        \begin{subfigure}{.24\linewidth}
@@ -272,7 +272,7 @@ Putting the arguments on top of pointers and not reserving space for the return
 \end{figure}
 
 Calling a function and referencing function arguments are an extension to $\mathcal{E}$ as shown below.
-Arguments may be at different places on the stack at different times (see \cref{ssec:step}) and therefore the exact location always is be determined from the context using \cleaninline{findarg}\footnote{\cleaninline{findarg [l`:r] l = if (l == l`) 0 (1 + findarg r l)}}.
+Arguments may be at different places on the stack at different times (see \cref{ssec:step}) and therefore the exact location is always is determined from the context using \cleaninline{findarg}\footnote{\cleaninline{findarg [l`:r] l = if (l == l`) 0 (1 + findarg r l)}}.
 Compiling argument $a_{f^i}$, the $i$th argument in function $f$, consists of traversing all positions in the current context.
 Arguments wider than one stack cell are fetched in reverse to reconstruct the original order.
 
@@ -376,7 +376,7 @@ It is special because in the generated function, the task value of a task is ins
 Furthermore, it is a lazy node in the task tree: the right-hand side may yield a new task tree after several rewrite steps, i.e.\ it is allowed to create infinite task trees using step combinators.
 The function is generated using the $\mathcal{S}$ scheme that requires two arguments: the context $r$ and the width of the left-hand side so that it can determine the position of the stability which is added as an argument to the function.
 The resulting function is basically a list of if-then-else constructions to check all predicates one by one.
-Some optimization is possible here but has currently not been implemented.
+Some optimisation is possible here but has currently not been implemented.
 
 \begin{align*}
        \cschemeE{t_1\text{\cleaninline{>>*.}}t_2}{r} & =
@@ -406,7 +406,7 @@ Some optimization is possible here but has currently not been implemented.
 First the context is evaluated.
 The context contains arguments from functions and steps that need to be preserved after rewriting.
 The evaluated context is combined with the left-hand side task value by means of a \cleaninline{.&&.} combinator to store it in the task tree so that it is available after a rewrite.
-This means that the task tree is be transformed as seen in \cref{lst:context_tree}.
+This means that the task tree is transformed as seen in \cref{lst:context_tree}.
 
 \begin{figure}
        \begin{subfigure}{.5\textwidth}
@@ -486,7 +486,7 @@ The \cleaninline{setSds} task evaluates the value, lifts that value to a task tr
 
 While there is no code generated in the definition, the byte code compiler is storing all \gls{SDS} data in the \cleaninline{bcs_sdses} field in the compilation state.
 Regular \glspl{SDS} are stored as \cleaninline{Right String255} values.
-The \glspl{SDS} are typed as functions in the host language so an argument for this function must be created that represents the \gls{SDS} on evaluation.
+The \glspl{SDS} are typed as functions in the host language, so an argument for this function must be created that represents the \gls{SDS} on evaluation.
 For this, an \cleaninline{BCInterpret} is created that emits this identifier.
 When passing it to the function, the initial value of the \gls{SDS} is returned.
 In the case of a local \gls{SDS}, this initial value is stored as a byte code encoded value in the state and the compiler continues with the rest of the program.
@@ -497,10 +497,10 @@ This is safe because the expression on the right-hand side of the \cleaninline{I
 Then, using \cleaninline{addSdsIfNotExist}, the identifier for this particular \gls{SDS} is either retrieved from the compiler state or generated freshly.
 This identifier is then used to provide a reference to the \cleaninline{def} definition to evaluate the main expression.
 Compiling \cleaninline{getSds} is a matter of executing the \cleaninline{BCInterpret} representing the \gls{SDS}, which yields the identifier that can be embedded in the instruction.
-Setting the \gls{SDS} is similar: the identifier is retrieved and the value is written to put in a task tree so that the resulting task can remember the value it has written.
+Setting the \gls{SDS} is similar: the identifier is retrieved, and the value is written to put in a task tree so that the resulting task can remember the value it has written.
 
 % VimTeX: SynIgnore on
-\begin{lstClean}[caption={Backend implementation for the SDS classes.},label={lst:comp_sds}]
+\begin{lstClean}[caption={Backend implementation for the \gls{SDS} classes.},label={lst:comp_sds}]
 :: Sds a = Sds Int
 instance sds BCInterpret where
        sds def = {main =
@@ -568,7 +568,7 @@ In the first phase, the communication channels are processed.
 The exact communication method is a customisable device-specific option baked into the \gls{RTS}.
 The interface is kept deliberately simple and consists of two layers: a link interface and a communication interface.
 Besides opening, closing and cleaning up, the link interface has three functions that are shown in \cref{lst:link_interface}.
-Consequently, implementing this link interface is very simple but it is still possible to implement more advanced link features such as buffering.
+Consequently, implementing this link interface is very simple, but it is still possible to implement more advanced link features such as buffering.
 There are implementations for this interface for serial or \gls{WIFI} connections using \gls{ARDUINO}, and \gls{TCP} connections for Linux.
 
 \begin{lstArduino}[caption={Link interface of the \gls{MTASK} \gls{RTS}.},label={lst:link_interface}]
@@ -592,13 +592,14 @@ There are several possible messages that can be received from the server:
 
 \begin{description}
        \item[SpecRequest]
-               is a message instructing the device to send its specification and it is received immediately after connecting.
+               is a message instructing the device to send its specification.
+               It is received immediately after connecting.
                The \gls{RTS} responds with a \texttt{Spec} answer containing the specification.
        \item[TaskPrep]
                tells the device a task is on its way.
                Especially on faster connections, it may be the case that the communication buffers overflow because a big message is sent while the \gls{RTS} is busy executing tasks.
                This message allows the \gls{RTS} to postpone execution for a while, until the larger task has been received.
-               The server sends the task only after the device acknowledged the preparation by by sending a \texttt{TaskPrepAck} message.
+               The server sends the task only after the device acknowledged the preparation by sending a \texttt{TaskPrepAck} message.
        \item[Task]
                contains a new task, its peripheral configuration, the \glspl{SDS}, and the byte code.
                The new task is immediately copied to the task storage but is only initialised during the next phase.
@@ -687,8 +688,8 @@ This approach allows for flexible ratios, i.e.\ many tasks and small trees or fe
 
 Stable tasks, and unreachable task tree nodes are removed.
 If a task is to be removed, tasks with higher memory addresses are moved down.
-For task trees---stored in the heap---the \gls{RTS} already marks tasks and task trees as trash during rewriting so the heap can be compacted in a single pass.
-This is possible because there is no sharing or cycles in task trees and nodes contain pointers pointers to their parent.
+For task trees---stored in the heap---the \gls{RTS} already marks tasks and task trees as trash during rewriting, so the heap can be compacted in a single pass.
+This is possible because there is no sharing or cycles in task trees and nodes contain pointers to their parent.
 
 
 \section{C code generation}\label{sec:ccodegen}
@@ -696,12 +697,12 @@ All communication between the \gls{ITASK} server and the \gls{MTASK} server is t
 From the structural representation of the type, a \gls{CLEAN} parser and printer is constructed using generic programming.
 Furthermore, a \ccpp{} parser and printer is generated for use on the \gls{MTASK} device.
 The technique for generating the \ccpp{} parser and printer is very similar to template metaprogramming and requires a rich generic programming library or compiler support that includes a lot of metadata in the record and constructor nodes.
-Using generic programming in the \gls{MTASK} system, both serialisation and deserialisation on the microcontroller and and the server is automatically generated.
+Using generic programming in the \gls{MTASK} system, both serialisation and deserialisation on the microcontroller and the server is automatically generated.
 
 \subsection{Server}
 On the server, off-the-shelve generic programming techniques are used to make the serialisation and deserialisation functions (see \cref{lst:ser_deser_server}).
 Serialisation is a simple conversion from a value of the type to a string.
-Deserialisation is a little bit different in order to support streaming\footnotemark.
+Deserialisation is a bit different in order to support streaming\footnotemark.
 \footnotetext{%
        Here the \cleaninline{*!} variant of the generic interface is chosen that has less uniqueness constraints for the compiler-generated adaptors \citep{alimarine_generic_2005,hinze_derivable_2001}.%
 }
@@ -771,7 +772,7 @@ This byte code is sent for interpretation to the light-weight \gls{RTS} of the e
 The \gls{RTS} first evaluates the main expression in the interpreter.
 The result of this evaluation, a run time representation of the task, is a task tree.
 This task tree is rewritten according to small-step reduction rules until a stable value is observed.
-Rewriting multiple tasks at the same time is achieved by interleaving the rewrite steps, resulting in seamingly parallel execution of the tasks.
+Rewriting multiple tasks at the same time is achieved by interleaving the rewrite steps, resulting in seemingly parallel execution of the tasks.
 All communication, including the serialisation and deserialisation, between the server and the \gls{RTS} is automated.
 From the structural representation of the types, printers and parsers are generated for the server and the client.
 
index 41e0dc7..bddea2a 100644 (file)
@@ -15,7 +15,7 @@
                \item an architectural overview of \gls{MTASK} applications;
                \item the interface for connecting devices;
                \item the interface for lifting \gls{MTASK} tasks to \gls{ITASK} tasks;
-               \item a interface for lowering \gls{ITASK} \glspl{SDS} to \gls{MTASK} \glspl{SDS};
+               \item the interface for lowering \gls{ITASK} \glspl{SDS} to \gls{MTASK} \glspl{SDS};
                \item and a non-trivial home automation example application using all integration mechanisms;
        \end{itemize}
 \end{chapterabstract}
@@ -73,7 +73,7 @@ The \cleaninline{MTDevice} abstract type is internally represented as three \gls
 The first \gls{SDS} is the information about the \gls{RTS} of the device, i.e.\ metadata on the tasks that are executing, the hardware specification and capabilities, and a list of fresh task identifiers.
 The second \gls{SDS} is a map storing downstream \gls{SDS} updates.
 When a lowered \gls{SDS} is updated on the device, a message is sent to the server.
-This message is initially queued in the map in order to properly handly multiple updates asychronously.
+This message is initially queued in the map in order to properly handle multiple updates asynchronously.
 Finally, the \cleaninline{MTDevices} type contains the communication channels.
 
 The \cleaninline{withDevice} task itself first constructs the \glspl{SDS} using the \gls{ITASK} function \cleaninline{withShared}.
@@ -109,7 +109,7 @@ This exception can be caught in order to devise fail-safe mechanisms.
 For example, if a device fails, the task can be sent to another device as can be seen in \cref{lst:failover}.
 This function executes an \gls{MTASK} task on a pool of devices connected through \gls{TCP}.
 If a device error occurs during execution, the next device in the pool is tried until the pool is exhausted.
-If another type of error occurs, it is rethrown for a parent task to catch.
+If another type of error occurs, it is re-thrown for a parent task to catch.
 
 \begin{lstClean}[caption={An \gls{MTASK} failover combinator.},label={lst:failover}]
        failover :: [TCPSettings] (Main (MTask BCInterpret a)) -> Task a
@@ -163,7 +163,7 @@ To mitigate this problem, \gls{MTASK} tasks can be preloaded on a device.
 Preloading means that the task is compiled and integrated into the device firmware.
 On receiving a \cleaninline{TaskPrep}, a hashed value of the task to be sent is included.
 The device then checks the preloaded task registry and uses the local preloaded version if the hash matches.
-Of course this only works for tasks that are not tailor made for the current work specification and not depend on run time information.
+Of course this only works for tasks that are not tailor-made for the current work specification and not depend on run time information.
 The interface for task preloading can be found in \cref{lst:preload}.
 Given an \gls{MTASK} task, a header file is created that should be placed in the source code directory of the \gls{RTS} before building to include it in the firmware.
 
@@ -236,7 +236,7 @@ The following section contains an elaborate example using all integration functi
 This section presents an interactive home automation program (\cref{lst:example_home_automation}) to illustrate the integration of the \gls{MTASK} language and the \gls{ITASK} system.
 It consists of a web interface for the user to control which tasks are executed on either one of two connected devices: an \gls{ARDUINO} UNO, connected via a serial port; and an ESP8266 based prototyping board called NodeMCU, connected via \gls{TCP}\slash{}\gls{WIFI}.
 \Crefrange{lst:example:spec1}{lst:example:spec2} show the specification for the devices.
-The UNO is connected via serial using the unix filepath \path{/dev/ttyACM0} and the default serial port settings.
+The UNO is connected via serial using the UNIX filepath \path{/dev/ttyACM0} and the default serial port settings.
 The NodeMCU is connected via \gls{WIFI} and hence the \cleaninline{TCPSettings} record is used.
 %Both types have \cleaninline{channelSync} instances.
 
index 01e0bc1..6ef7512 100644 (file)
@@ -25,7 +25,7 @@ It is implemented as an \gls{EDSL} in \gls{CLEAN} using class-based---or tagless
 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 intepretations.
+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 and adding an interpretation is done by creating a new data type and providing implementations for the various type classes.
 
 \section{Class-based shallow embedding}
@@ -90,7 +90,7 @@ As it is shallowly embedded, the types of the terms in the language can be const
 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 serialization, printing, \gls{ITASK} constraints, \etc\ \citep[\citesection{6.9}]{plasmeijer_clean_2021}.
+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}.
@@ -124,7 +124,7 @@ class basicType t | type t where ...
 
 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 perpipherals or lowered \gls{ITASK} \glspl{SDS} are not included in this class collection because not all devices or interpretations support this.
+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
@@ -223,7 +223,7 @@ e2 = If (e0 ==. int e1)
 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 pecularities.
+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}.}]
@@ -260,7 +260,7 @@ class tupl v where
 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} language only allows first-order functions and no partial function application.
-To restrict this, a multi-paramater type class is used instead of a type class with one type variable.
+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.
@@ -375,7 +375,7 @@ class delay v :: (v n) -> MTask v n | long v n
 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 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 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.
@@ -391,7 +391,7 @@ The first argument of the functions in this class is overloaded, i.e.\ it accept
 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 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 finisheds and yields a stable unit value.
+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.
 
@@ -469,7 +469,7 @@ Sequential task combination allows the right-hand side expression to \emph{obser
 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.
 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 this continuations.
+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.
@@ -624,7 +624,7 @@ task = declarePin D3 PMInput \d3->
 
 \section{Interpretations}
 This section describes all the interpretations that the \gls{MTASK} language has.
-Not all of these interpretations are necessarily \gls{TOP} engines, i.e.\ not all the interpretations execute the resulting tasks.
+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}
@@ -635,7 +635,7 @@ It runs the pretty printer and returns a list of strings containing the pretty p
 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 entrypoint for the pretty printing interpretation.},label={lst:showmain}]
+\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}
@@ -654,11 +654,11 @@ blinkTask =
 
 \subsection{Simulator}
 The simulator converts the expression to a ready-for-work \gls{ITASK} simulation.
-There is one entrypoint for this interpretation (see \cref{lst:simulatemain}).
+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 entrypoint for the simulation interpretation.},label={lst:simulatemain}]
+\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}
index ee000b0..de58f8e 100644 (file)
@@ -2,10 +2,10 @@
 
 \input{subfilepreamble}
 
-\let\ifSubfilesClassLoadedOld\ifSubfilesClassLoaded%
-\ifSubfilesClassLoadedOld{
-       \renewcommand{\ifSubfilesClassLoaded}[2]{#2}
-}{}
+%\let\ifSubfilesClassLoadedOld\ifSubfilesClassLoaded%
+%\ifSubfilesClassLoadedOld{
+%      \renewcommand{\ifSubfilesClassLoaded}[2]{#2}
+%}{}
 \begin{document}
 \input{subfileprefix}
 \part[Orchestrating the Internet of Things using Task-O\-rien\-ted Programming]{\\[2ex]\smaller{}Orchestrating the Internet of Things using Task-O\-rien\-ted Programming}%
@@ -18,6 +18,6 @@
 \subfile{green}  % Green computing
 \subfile{finale} % Conclusion
 
-\let\ifSubfilesClassLoaded\ifSubfilesClassLoadedOld%
+%\let\ifSubfilesClassLoaded\ifSubfilesClassLoadedOld%
 \input{subfilepostamble}
 \end{document}
index 32466a5..3854bdd 100644 (file)
@@ -15,7 +15,6 @@
 
        We report a systematic comparative evaluation of two tierless language technologies for \gls{IOT} stacks: one for resource-rich sensor nodes (\gls{CLEAN} with \gls{ITASK}), and one for resource-constrained sensor nodes (\gls{CLEAN} with \gls{ITASK} and \gls{MTASK}).
        The evaluation is based on four implementations of a typical smart campus application: two tierless and two \gls{PYTHON}-based tiered.
-       %, with two targeting microcontrollers and two targeting supersensors.
        \begin{enumerate*}
                \item We show that tierless languages have the potential to significantly reduce the development effort for \gls{IOT} systems, requiring 70\% less code than the tiered implementations. Careful analysis attributes this code reduction to reduced interoperation (e.g.\ two \glspl{EDSL} and one paradigm versus seven languages and two paradigms), automatically generated distributed communication, and powerful \gls{IOT} programming abstractions.
                \item We show that tierless languages have the potential to significantly improve the reliability of \gls{IOT} systems, describing how \cimtask{} maintains type safety, provides higher order failure management, and simplifies maintainability.
@@ -34,7 +33,7 @@ Conventional \gls{IOT} software architectures require the development of separat
        \item Interoperating components in multiple languages and paradigms increases the developer's cognitive load who must simultaneously think in multiple languages and paradigms, i.e.\ manage significant semantic friction.
        \item The developer must correctly interoperate the components, e.g.\ adhere to the \gls{API} or communication protocols between components.
        \item To ensure correctness the developer must maintain type safety across a range of very different languages and diverse type systems.
-       \item The developer must deal with the potentially diverse failure modes of each component, and of component interoperations.
+       \item The developer must deal with the potentially diverse failure modes of each component, and of component interoperation.
 \end{enumerate*}
 
 A radical alternative development paradigm uses a single \emph{tierless} language that synthesizes all components\slash{}tiers in the software stack. There are established \emph{tierless} languages for web stacks, e.g.\ Links \citep{cooper2006links} or Hop \citep{serrano2006hop}.
@@ -49,7 +48,7 @@ Potentially a tierless language both reduces the development effort and improves
 This paper reports a systematic comparative evaluation of two tierless language technologies for \gls{IOT} stacks: one targeting resource-constrained microcontrollers, and the other resource-rich supersensors. The basis of the comparison is four implementations of a typical smart campus \gls{IOT} stack \citep{hentschel_supersensors:_2016}. Two implementations are conventional tiered \gls{PYTHON}-based stacks: \gls{PRS} and \gls{PWS}. The other two implementations are tierless: \gls{CRS} and \gls{CWS}. Our work makes the following research contributions, and the key results are summarised, discussed, and quantified in \cref{sec_t4t:Conclusion}.
 
 \begin{description}
-       \item[C1] We show that \emph{tierless languages have the potential to significantly reduce the development effort for \gls{IOT} systems}.
+       \item[C1] We show that \emph{tierless languages have the potential to significantly reduce the development effort for \gls{IOT} systems}.\label{enum:c1}
                We systematically compare code size (\gls{SLOC}) of the four smart campus implementations as a measure of development effort and maintainability \citep{alpernaswonderful,rosenberg1997some}.
                The tierless implementations require 70\% less code than the tiered implementations. We analyse the codebases to attribute the code reduction to three factors.
                \begin{enumerate*}
@@ -86,18 +85,18 @@ We have deployed sensor nodes into 12 rooms in two buildings. The \gls{IOT} syst
 access to sensor data through a RESTful \gls{API}.
 This allows campus stakeholders to add functionality at a business layer above the layers that we consider here. To date,
 simple apps have been developed including room temperature
-monitors and campus utilization maps \citep{hentschel_supersensors:_2016}.
+monitors and campus utilisation maps \citep{hentschel_supersensors:_2016}.
 A longitudinal study of sensor accuracy has also been
 conducted \citep{harth_predictive_2018}.
 
 \subsection{\IOT{} applications}%
 \label{sec_t4t:Stacks}
 
-Web applications are necessarily complex distributed systems, with client browsers interacting with a remote webserver and data store. Typical \gls{IOT} applications
+Web applications are necessarily complex distributed systems, with client browsers interacting with a remote web server and data store. Typical \gls{IOT} applications
 are even more complex as they combine a web application with a second distributed system of sensor and actuator nodes that collect and aggregate data, operate on it, and communicate with the server.
 
 Both web and \gls{IOT} applications are commonly structured into tiers, e.g.\ the classical four-tier Linux, Apache, MySQL and PHP (LAMP) stack.
-\Gls{IOT} stacks typically have more tiers than webapps, with the number depending on the complexity of the application \citep{sethi2017internet}. While other tiers, like the business layer \citep{muccini2018iot} may be added above them, the focus of our study is on programming the lower four tiers of the \gls{PRS}, \gls{CRS}, \gls{PWS} and \gls{CWS} stacks, as illustrated in \cref{fig_t4t:iot_arch}.
+\Gls{IOT} stacks typically have more tiers than web applications, with the number depending on the complexity of the application \citep{sethi2017internet}. While other tiers, like the business layer \citep{muccini2018iot} may be added above them, the focus of our study is on programming the lower four tiers of the \gls{PRS}, \gls{CRS}, \gls{PWS} and \gls{CWS} stacks, as illustrated in \cref{fig_t4t:iot_arch}.
 
 \begin{description}[style=sameline]
        \item [Perception layer] collects the data, interacts with the environment, and consists of devices using light, sound, motion, air quality and temperature sensors.
@@ -140,7 +139,7 @@ structure complex software is a common software engineering practice that provid
 However, a tiered architecture poses significant challenges for developers of \gls{IOT} and other software. The tiered \gls{PYTHON} \gls{PRS} and \gls{PWS} stacks exhibit these challenges, and we analyse these in detail later in the paper.
 
 \begin{description}[style=sameline]
-       \item[Polyglot development] the developer must be fluent in all the languages and components in the stack, known as being a full-stack developer for webapps \citep{mazzei2018full}. That is, the developer must correctly use multiple languages that have different paradigms, i.e.\ manage significant \emph{semantic friction} \citep{ireland_classification_2009}. For example the \gls{PWS} developer must integrate components written in seven languages with two paradigms (\cref{sec_t4t:interoperation}).
+       \item[Polyglot development] the developer must be fluent in all the languages and components in the stack, known as being a full-stack developer for web applications \citep{mazzei2018full}. That is, the developer must correctly use multiple languages that have different paradigms, i.e.\ manage significant \emph{semantic friction} \citep{ireland_classification_2009}. For example the \gls{PWS} developer must integrate components written in seven languages with two paradigms (\cref{sec_t4t:interoperation}).
        \item[Correct interoperation] the developer must adhere to the \gls{API} or communication protocols between components. \Cref{sec_t4t:codesize,sec_t4t:resourcerich} show that communication requires some 17\% of \gls{PRS} and \gls{PWS} code, so around 100 \gls{SLOC}. \Cref{sec_t4t:Communication} discusses the complexity of writing this distributed communication code.
        \item[Maintaining type safety] is a key element of the semantic friction encountered in multi-language stacks, and crucial for correctness. The developer must maintain type safety across a range of very different languages and diverse type systems, with minimal tool support. We show an example where \gls{PRS} loses type safety over the network layer (\Cref{sec_t4t:typesafety}).
        \item[Managing multiple failure modes] different components may have different failure modes, and these must be coordinated. \Cref{sec_t4t:NetworkManagement} outlines how \gls{PRS} and \gls{PWS} use heartbeats to manage failures.
@@ -151,7 +150,7 @@ An earlier empirical study of GitHub shows that using more languages to implemen
 A study of \gls{IOT} stack developers found that interoperation poses a real challenge, that microservices blur the abstraction between tiers, and that both testing and scaling \gls{IOT} applications to more devices are hard \citep{motta2018challenges}.
 
 One way of minimising the challenges of developing tiered polyglot \gls{IOT} software is to standardise and reuse components. This approach has been hugely successful for web stacks, e.g.\ browser standards. The W3C
-Web of Things aims to facilitate re-use by providing standardised metadata and other re-usable technological \gls{IOT} building blocks \citep{guinard_building_2016}. However, the Web of Things has yet to gain widespread adoption. Moreover, as it is based on web technology, it requires the \emph{thing} to run a web server, significantly increasing the hardware requirements.
+Web of Things aims to facilitate re-use by providing standardised metadata and other re-useable technological \gls{IOT} building blocks \citep{guinard_building_2016}. However, the Web of Things has yet to gain widespread adoption. Moreover, as it is based on web technology, it requires the \emph{thing} to run a web server, significantly increasing the hardware requirements.
 
 \section{Tierless languages}%
 \label{sec_t4t:TiredvsTierless}
@@ -159,7 +158,7 @@ Web of Things aims to facilitate re-use by providing standardised metadata and o
 A radical approach to overcoming the challenges raised by tiered distributed software is to use a tierless programming language that eliminates the semantic friction between tiers by generating code for all tiers, and all communication between tiers, from a single program. 
 Typically a tierless program uses a single language, paradigm and type system, and the entire distributed system is simultaneously checked by the compiler.
 
-There is intense interest in developing tierless, or multitier, language technologies with a number of research languages developed over the last fifteen years, e.g.\ \citep{cooper2006links, serrano2006hop, troyer_building_2018, 10.1145/2775050.2633367}. These languages demonstrate the
+There is intense interest in developing tierless, or multi-tiered, language technologies with a number of research languages developed over the last fifteen years, e.g.\ \citep{cooper2006links, serrano2006hop, troyer_building_2018, 10.1145/2775050.2633367}. These languages demonstrate the
 advantages of the paradigm, including less development effort, better maintainability, and sound semantics of distributed execution. At the same time a number of industrial technologies incorporate tierless concepts, e.g.\ \citep{balat2006ocsigen, bjornson2010composing, strack2015getting}. These languages demonstrate the benefits of the paradigm in practice. Some tierless languages use (embedded) \glspl{DSL} to specify parts of the multi-tier software.
 
 Tierless languages have been developed for a range of distributed paradigms, including web applications, client-server applications, mobile applications, and generic distributed systems. A recent and substantial survey of these tierless technologies is available \citep{weisenburger2020survey}. Here we provide a brief introduction to tierless languages with a focus on \gls{IOT} software.
@@ -170,7 +169,7 @@ There are established tierless languages for web development, both standalone la
 Example standalone tierless web languages are Links \citep{cooper2006links} and Hop \citep{serrano2006hop}.
 From a single declarative program the client, server and database code is simultaneously checked by the compiler, and compiled to the required component languages. For example, Links compiles to HTML and JavaScript for the client side and to SQL on the server-side to interact with the database system.
 
-An example tierless web framework that uses a \gls{DSL} is Haste \citep{10.1145/2775050.2633367}, that embeds the \gls{DSL} in \gls{HASKELL}. Haste programs are compiled multiple times: the server code is generated by the standard \gls{GHC} \gls{HASKELL} compiler \citep{hall1993glasgow}; Javascript for the client is generated by a custom \gls{GHC} compiler backend. The design leverages \gls{HASKELL}'s high-level programming abstractions and strong typing, and benefits from \gls{GHC}: a mature and sophisticated compiler.
+An example tierless web framework that uses a \gls{DSL} is Haste \citep{10.1145/2775050.2633367}, that embeds the \gls{DSL} in \gls{HASKELL}. Haste programs are compiled multiple times: the server code is generated by the standard \gls{GHC} \gls{HASKELL} compiler \citep{hall1993glasgow}; JavaScript for the client is generated by a custom \gls{GHC} compiler backend. The design leverages \gls{HASKELL}'s high-level programming abstractions and strong typing, and benefits from \gls{GHC}: a mature and sophisticated compiler.
 
 
 \subsection{Tierless \IOT{} languages}
@@ -210,7 +209,7 @@ A key challenge for a tierless language is to determine which parts of the progr
 
 For example a tierless web language must identify client code to ship to browsers, database code to execute in the DBMS, and application code to run on the server.
 Tierless web languages can make this determination statically, so-called \emph{tier splitting} using types or syntactic markers like \texttt{server} or \texttt{client} pragmas \citep{cooper2006links,10.1145/2775050.2633367}.
-It is even possible to infer the splitting, relieving the developers from the need to specify it, as illustrated for Javascript as a tierless web language \citep{10.1145/2661136.2661146}.
+It is even possible to infer the splitting, relieving the developers from the need to specify it, as illustrated for JavaScript as a tierless web language \citep{10.1145/2661136.2661146}.
 
 In \cimtask{} and \citask{} tier splitting is specified by functions, e.g.\ the \cimtask{} \cleaninline{asyncTask} function identifies a task for execution on a remote device and \cleaninline{liftmTask} executes the given task on an \gls{IOT} device.
 The tier splitting functions are illustrated in examples in the next section, e.g.\ on \cref{lst_t4t:itaskTempFull:startdevtask} in \cref{lst_t4t:itaskTempFull} and \cref{lst_t4t:mtasktemp:liftmtask} in \cref{lst_t4t:mtasktemp}.
@@ -230,8 +229,8 @@ In general different tierless languages specify placement in different ways, e.g
 
 \Cimtask{} and \citask{} both use dynamic task placement.
 In \cimtask{} sensor nodes are programmed once with the \gls{MTASK} \gls{RTS}, and possibly some precompiled tasks.
-Thereafter a sensor node can dynamically receive \gls{MTASK} programs, compiled at runtime by the server.
-In \citask{} the sensor node runs an \gls{ITASK} server that recieves and executes code from the (\gls{IOT}) server \citep{oortgiese_distributed_2017}.
+Thereafter, a sensor node can dynamically receive \gls{MTASK} programs, compiled at runtime by the server.
+In \citask{} the sensor node runs an \gls{ITASK} server that receives and executes code from the (\gls{IOT}) server \citep{oortgiese_distributed_2017}.
 Placement happens automatically as part of the first-class splitting constructs, so \cref{lst_t4t:mtasktemp:liftmtask} in \cref{lst_t4t:mtasktemp} places \cleaninline{devTask} onto the \cleaninline{dev} sensor node.
 
 \subsubsection{Communication}\label{ssec_t4t:communication}
@@ -243,13 +242,13 @@ Tierless languages may adopt a range of communication paradigms for communicatin
 
 \subsubsection{Security}\label{ssec_t4t:security}
 
-Security is a major issue and a considerable challenge for many \gls{IOT} systems \citep{alhirabi_security_2021}. There are potentially security issues at each layer in an \gls{IOT} application (\cref{fig_t4t:iot_arch}). The security issues and defence mechanisms at the application and presentation layers are relatively standard, e.g.\ defending against SQL injection attacks. The security issues at the network and perception layers are more challenging. Resource-rich sensor nodes can adopt some standard security measures like encrypting messages, and regularly applying software patches to the operating system. However microcontrollers often lack the computational resources for encryption, and it is hard to patch their system software because the program is often stored in flash memory. In consequence there are infamous examples of \gls{IOT} systems being hijacked to create botnets \citep{203628,herwig_measurement_2019}.
+Security is a major issue and a considerable challenge for many \gls{IOT} systems \citep{alhirabi_security_2021}. There are potentially security issues at each layer in an \gls{IOT} application (\cref{fig_t4t:iot_arch}). The security issues and defence mechanisms at the application and presentation layers are relatively standard, e.g.\ defending against SQL injection attacks. The security issues at the network and perception layers are more challenging. Resource-rich sensor nodes can adopt some standard security measures like encrypting messages, and regularly applying software patches to the operating system. However, microcontrollers often lack the computational resources for encryption, and it is hard to patch their system software because the program is often stored in flash memory. In consequence there are infamous examples of \gls{IOT} systems being hijacked to create botnets \citep{203628,herwig_measurement_2019}.
 
 Securing the entire stack in a conventional tiered \gls{IOT} application is particularly challenging as the stack is implemented in a collection of programming languages with low level programming and communication abstractions. In such polyglot distributed systems it is hard to determine, and hence secure, the flow of data between components. In consequence a small mistake may have severe security implications. 
 
 A number of characteristics of tierless languages help to improve security. Communication and placement vulnerabilities are minimised as communication and placement are automatically generated and checked by the compiler. So injection attacks and the exploitation of communication\slash{}placement protocol bugs are less likely. Vulnerabilities introduced by mismatched types are avoided as the entire system is type checked. Moreover, tierless languages can exploit language level security techniques. For example languages like Jif\slash{}split \citep{zdancewic2002secure} and Swift \citep{chong2007secure} place components to protect the security of data. Another example are programming language technologies for controlling information flow, and these can be used to improve security. For example Haski uses them to improve the security of \gls{IOT} systems \citep{valliappan_towards_2020}. 
 
-However many tierless languages have yet to provide a comprehensive set of security technologies, despite its importance in domains like web and \gls{IOT} applications. For example Erlang and many Erlang-based systems \citep{shibanai_distributed_2018,sivieri2012drop}, lack important security measures. Indeed security is not covered in a recent, otherwise comprehensive, survey of tierless technologies \citep{weisenburger2020survey}.
+However, many tierless languages have yet to provide a comprehensive set of security technologies, despite its importance in domains like web and \gls{IOT} applications. For example Erlang and many Erlang-based systems \citep{shibanai_distributed_2018,sivieri2012drop}, lack important security measures. Indeed, security is not covered in a recent, otherwise comprehensive, survey of tierless technologies \citep{weisenburger2020survey}.
 
 \Citask{} and \cimtask{} are typical in this respect: little effort has yet been expended on improving their security. Of course as tierless languages they benefit from static type safety and automatically generated communication and placement. Some preliminary work shows that, as the communication between layers is protocol agnostic, more secure alternatives can be used. One example is to run the \gls{ITASK} server behind a reverse proxy implementing TLS\slash{}SSL encryption \citep{wijkhuizen_security_2018}. A second is to add integrity checks or even encryption to the communication protocol for resource-rich sensor nodes \citep{de_boer_secure_2020}.
 
@@ -267,7 +266,7 @@ Both \gls{CLEAN} and \gls{HASKELL} support fairly similar models of generic prog
 \Gls{TOP} is a declarative programming paradigm for constructing interactive distributed systems \citep{plasmeijer_task-oriented_2012}.
 Tasks are the basic blocks of \gls{TOP} and represent work that needs to be done in the broadest sense.
 Examples of typical tasks range from allowing a user to complete a form, controlling peripherals, moderating other tasks, or monitoring a database.
-From a single declarative description of tasks all of the required software components are generated.
+From a single declarative description of tasks all the required software components are generated.
 This may include web servers, client code for browsers or \gls{IOT} devices, and for their interoperation.
 That is, from a single \gls{TOP} program the language implementation automatically generates an \emph{integrated distributed system}.
 Application areas range from simple web forms or blinking \glspl{LED} to multi-user distributed collaboration between people and machines \citep{oortgiese_distributed_2017}.
@@ -285,10 +284,10 @@ parametric lenses define a specific view on \pgls{SDS}.
 \subsection{The iTask eDSL}%
 \label{sec_t4t:itasks}
 The \gls{ITASK} \gls{EDSL} is designed for constructing multi-user distributed applications, including web \citep{TOP-ICFP07} or \gls{IOT} applications.
-Here we present \gls{ITASK} by example, and the first is a complete program to repeatedly read the room temperature from a digital humidity and temperature (DHT) sensor attached to the machine and display it on a web page (\cref{lst_t4t:itaskTemp}).
+Here we present \gls{ITASK} by example, and the first is a complete program to repeatedly read the room temperature from a \gls{DHT} sensor attached to the machine and display it on a web page (\cref{lst_t4t:itaskTemp}).
 The first line is the module name, the third imports the \cleaninline{iTask} module, and the main function (\cref{lst_t4t:itaskTemp:systemfro,lst_t4t:itaskTemp:systemto}) launches \cleaninline{readTempTask} and the \gls{ITASK} system to generate the web interface in \cref{fig_t4t:itaskTempSimple}.
 
-Interaction with a device like the DHT sensor using a protocol like 1-Wire or \gls{I2C} is abstracted into a library. So the \cleaninline{readTempTask} task starts by creating a \cleaninline{dht} sensor object (\cref{lst_t4t:itaskTemp:dhtDef}) thereafter \cleaninline{repeatEvery} executes a task at the specified \cleaninline{interval}. This task reads the temperature from the \cleaninline{dht} sensor, and with a sequential composition combinator \cleaninline{>>~} passes the \cleaninline{temp} value to \cleaninline{viewInformation} that displays it on the web page (\cref{lst_t4t:itaskTemp:viewInformation}).
+Interaction with a device like the \gls{DHT} sensor using a protocol like 1-Wire or \gls{I2C} is abstracted into a library. So the \cleaninline{readTempTask} task starts by creating a \cleaninline{dht} sensor object (\cref{lst_t4t:itaskTemp:dhtDef}) thereafter \cleaninline{repeatEvery} executes a task at the specified \cleaninline{interval}. This task reads the temperature from the \cleaninline{dht} sensor, and with a sequential composition combinator \cleaninline{>>~} passes the \cleaninline{temp} value to \cleaninline{viewInformation} that displays it on the web page (\cref{lst_t4t:itaskTemp:viewInformation}).
 The tuning combinator \cleaninline{<<@} adds a label to the web editor displaying the temperature. Crucially, the \gls{ITASK} implementation transparently ships parts of the code for the web-interface to be executed in the browser, and \cref{fig_t4t:itaskTempSimple} shows the UML deployment diagram.
 
 \begin{lstClean}[%
@@ -333,7 +332,7 @@ SimpleTempSensor only reports instantaneous temperature measurements. Extending
 
 TempHistory defines two tasks that interact with the \texttt{mea\-sure\-ments\-SDS}: \texttt{mea\-sure\-Task} adds measurements at each detected change in the temperature.
 It starts by defining a \cleaninline{dht} object as before, and then defines a recursive \cleaninline{task} function parameterised by the \cleaninline{old} temperature.
-This function reads the temperature from the DHT sensor and uses the step combinator, \cleaninline{>>*}, to compose it with a list of actions.
+This function reads the temperature from the \gls{DHT} sensor and uses the step combinator, \cleaninline{>>*}, to compose it with a list of actions.
 The first of those actions that is applicable determines the continuation of this task. If no action is applicable, the task on the left-hand side is evaluated again.
 The first action checks whether the new temperature is different from the \cleaninline{old} temperature (\cref{lst_t4t:itaskTemp:action1}). If so, it records the current time and adds the new measurements to the \cleaninline{measurementsSDS}.
 The next action in \cref{lst_t4t:itaskTemp:action2} is always applicable and waits (sleeps) for an interval before returning the old temperature.
@@ -341,7 +340,7 @@ On \cref{lst_t4t:itaskTemp:launch} \cleaninline{task} is launched with an initia
 
 \begin{lstClean}[%
        numbers=left,
-       caption={TempHistory: a tierless \citask{} webapplication that records and manipulates timed temperatures.},
+       caption={TempHistory: a tierless \citask{} web application that records and manipulates timed temperatures.},
        label={lst_t4t:TempHistory}]
 module TempHistory
 
@@ -485,7 +484,7 @@ mainTask [+\label{lst_t4t:itaskTempFull:main}+]
 
 In many \gls{IOT} systems the sensor nodes are resource constrained, e.g.\ inexpensive microcontrollers. These are far cheaper, and consume far less power, than a single-board computer like a Raspberry Pi. Microcontrollers also allow the programmer to easily control peripherals like sensors and actuators via the \gls{IO} pins of the processor.
 
-microcontrollers have limited memory capacity, compute power and communication bandwidth, and hence typically no \gls{OS}.
+Microcontrollers have limited memory capacity, compute power and communication bandwidth, and hence typically no \gls{OS}.
 These limitations make it impossible to run an \gls{ITASK} server:
 there is no \gls{OS} to start the remote task, the code of the task is too big to fit in the available memory and the microcontroller processor is too slow to run it.
 The \gls{MTASK} \gls{EDSL} is designed to bridge this gap: \gls{MTASK} tasks can be communicated from the server to the sensor node, to execute within the limitations of a typical microcontroller, while providing programming abstractions that are consistent with \gls{ITASK}.
@@ -493,7 +492,7 @@ The \gls{MTASK} \gls{EDSL} is designed to bridge this gap: \gls{MTASK} tasks can
 Like \gls{ITASK}, \gls{MTASK} is task oriented, e.g.\ there are primitive tasks that produce intermediate values, a restricted set of task combinators to compose the tasks, and (recursive) functions to construct tasks.
 Tasks in \gls{MTASK} communicate using task values or \glspl{SDS} that may be local or remote, and may be shared by some \gls{ITASK} tasks.
 
-Apart from the \gls{EDSL}, the \gls{MTASK} system contains a featherlight domain-specific \emph{operating system} running on the microcontroller.
+Apart from the \gls{EDSL}, the \gls{MTASK} system contains a feather-light domain-specific \emph{operating system} running on the microcontroller.
 This \gls{OS} task scheduler receives the byte code generated from one or more \gls{MTASK} programs and interleaves the execution of those tasks. The \gls{OS} also manages \gls{SDS} updates and the passing of task results.
 The \gls{MTASK} \gls{OS} is stored in flash memory while the tasks are stored in \gls{RAM} to minimise wear on the flash memory. While sending byte code to a sensor node at runtime greatly increases the amount of communication, this can be mitigated as any tasks known at compile time can be preloaded on the microcontroller.
 In contrast, compiled programs, like \ccpp{}, are stored in flash memory and there can only ever be a few thousand programs uploaded during the lifetime of the microcontroller before exhausting the flash memory. 
@@ -686,15 +685,12 @@ All four smart campus implementations meet these high-level requirements.
 Observation of the four implementations shows that they operate as expected, e.g.\ detecting light or motion. To illustrate \cref{fig_t4t:webinterfaces} shows the web interface for the implementations where \gls{CWS} and \gls{CRS} are deployed in a different room from \gls{PWS} and \gls{PRS}.
 
 All four implementations use an identical set of inexpensive sensors, so we expect the accuracy of the data collected is within tolerance levels. This is validated by comparing \gls{PRS} and \gls{PWS} sensor nodes deployed in the same room for some minutes. The measurements show only small variances, e.g.\ temperatures recorded differ by less than \qty{0.4}{\celcius}, and light by less than \qty{1}{lux}. For this room monitoring application precise timings are not critical, and we don't compare the timing behaviours of the implementations.
-% Phil: lets see what the reviewers say
-
 
 \subsubsection{Memory and power consumption}%
 %\subsubsection{Memory Consumption}%
 \label{sec_t4t:MemPower}
 
 \paragraph{Memory} By design sensor nodes are devices with limited computational capacity, and memory is a key restriction. Even supersensors often have less than a \unit{\gibi\byte} of memory, and microcontrollers often have just tens of \unit{\kibi\byte}.
-%In a tiered implementation the memory residency of the sensor node code can be minimised by carefully crafting it in a language that minimises memory residency. However, ...
 As the tierless languages synthesize the code to be executed on the sensor nodes, we need to confirm that the generated code is sufficiently memory efficient.
 
 \begin{table}
@@ -714,7 +710,6 @@ As the tierless languages synthesize the code to be executed on the sensor nodes
 In \gls{PWS}, the hand-written \gls{MICROPYTHON} is compiled to byte code for execution on the virtual machine. Low residency is achieved with a fixed size heap and efficient memory management. For example both \gls{MICROPYTHON} and \gls{MTASK} use fixed size allocation units and mark\&sweep garbage collection to minimise memory usage at the cost of some execution time \citep{plamauer2017evaluation}.
 
 The smart campus sensor node programs executing on the Raspberry Pis have far higher maximum residencies than those executing on the microcontrollers: \qty{3.5}{\mebi\byte} for \gls{PRS} and \qty{2.7}{\mebi\byte} for \gls{CRS}. In \gls{CRS} the sensor node code is a set of \gls{ITASK} executing on a full-fledged \gls{ITASK} server running in distributed child mode and this consumes far more memory.
-%The memory used is actually very similar to the memory usage of the server with a single client connected.
 In \gls{PRS} the sensor node program is written in \gls{PYTHON}, a language far less focused on minimising memory usage than \gls{MICROPYTHON}. For example an object like a string is larger in \gls{PYTHON} than in \gls{MICROPYTHON} and consequently does not support all features such as \emph{f-strings}.
 Furthermore, not all advanced \gls{PYTHON} feature regarding classes are available in \gls{MICROPYTHON}, i.e.\ only a subset of the \gls{PYTHON} specification is supported \citep{diffmicro}.
 
@@ -731,13 +726,8 @@ The Raspberry Pi supersensor node used in \gls{CRS} and \gls{PRS} use more power
 This section investigates whether tierless languages make \gls{IOT} programming \emph{easier} by comparing the \gls{UOG} smart campus implementations. The \gls{CRS} and \gls{CWS} implementations allow us to evaluate tierless languages for
  resource-rich and for resource-constrained sensor nodes respectively. The \gls{PRS} and \gls{PWS} allow a like-for-like comparison with tiered \gls{PYTHON} implementations.
 
-
-%\subsection{Temperature Sensor Illustration}
-
 \subsection{Comparing tiered and tierless codebases}%
 \label{sec_t4t:codesize}
-%A comparison of the Temperature sensor in \gls{PYTHON} Micropyton, Itask \& \gls{MTASK}.
-
 \paragraph{Code size}
 is widely recognised as an approximate measure of the development and maintenance effort required for a software system \citep{rosenberg1997some}. \Gls{SLOC} is a common code size metric, and is especially useful for multi-paradigm systems like \gls{IOT} systems. It is based on the simple principle that the more \gls{SLOC}, the more developer effort and the increased likelihood of bugs \citep{rosenberg1997some}. It is a simple measure, not dependent on some formula, and can be automatically computed \citep{sheetz2009understanding}.
 
@@ -746,7 +736,6 @@ Of course \gls{SLOC} must be used carefully as it is easily influenced by progra
 \Cref{table_t4t:multi} enumerates the \gls{SLOC} required to implement the \gls{UOG} smart campus functionalities in \gls{PWS}, \gls{PRS}, \gls{CWS} and \gls{CRS}. Both \gls{PYTHON} and \gls{CLEAN} implementations use the same server and communication code for Raspberry Pi and for \gls{WEMOS} sensor nodes (rows 5--7 of the table).
 The Sensor Interface (SI) refers to code facilitating the communication between the peripherals and the sensor node software. % formerly hardware interface
 Sensor Node (SN) code contains all other code on the sensor node that does not belong to any another category, such as control flow. % formerly device output
-%Server communication denotes code that provides the high level communication between the sensor node and the server.
 Manage Nodes (MN) is code that coordinates sensor nodes, e.g.\ to add a new sensor node to the system. % formerly device management
 Web Interface (WI) code provides the web interface from the server, i.e.\ the presentation layer.
 Database Interface (DI) code communicates between the server and the database\strut(s).
@@ -790,7 +779,6 @@ While this is a little less than the 106 \gls{SLOC} used in \gls{PYTHON} (\cref{
 Idiomatic \citask{} would use high level abstractions to store persistent data in \pgls{SDS}, requiring just a few \gls{SLOC}.
 The total size of \gls{CWS} and \gls{CRS} would be reduced by a factor of two and the percentage of Database Interface code would be even less than in the tiered \gls{PYTHON} implementations.
 
-
 \begin{figure}
        \centering
        \includegraphics[width=.7\linewidth]{bar_chart.pdf}
@@ -876,8 +864,7 @@ The tierless implementations use just two conceptually-similar \glspl{DSL} embed
 
 Interoperation \emph{increases the cognitive load on the developer} who must simultaneously think in multiple languages and paradigms. This is commonly known as semantic friction or impedance mismatch \citep{ireland_classification_2009}. A simple illustration of this is that the tiered \gls{PRS} source code comprises some 38 source and configuration files, whereas the tierless \gls{CRS} requires just 3 files (\cref{table_t4t:multi}). The source could be structured as a single file, but to separate concerns is structured into three modules, one each for \glspl{SDS}, types, and control logic \citep{wang_maintaining_2018}.
 
-The developer must \emph{correctly interoperate the components}, e.g.\ adhere to the \gls{API} or communication protocols between components. The interoperation often entails additional programming tasks like marshalling or demarshalling data between components. For example, in the tiered \gls{PRS} and \gls{PWS} architectures, \gls{JSON} is used to serialise and deserialise data strings from the \gls{PYTHON} collector component before storing the data in the Redis database (\cref{lst_t4t:json}).
-%e.g.\ to marshall and demarshall data between components.
+The developer must \emph{correctly interoperate the components}, e.g.\ adhere to the \gls{API} or communication protocols between components. The interoperation often entails additional programming tasks like marshalling or unmarshalling data between components. For example, in the tiered \gls{PRS} and \gls{PWS} architectures, \gls{JSON} is used to serialise and deserialise data strings from the \gls{PYTHON} collector component before storing the data in the Redis database (\cref{lst_t4t:json}).
 
 \begin{lstPython}[caption={\Gls{JSON} Data marshalling in \gls{PRS} and \gls{PWS}: sensor node above, server below.},label={lst_t4t:json}]
 
@@ -977,20 +964,16 @@ and the \cleaninline{viewSharedInformation} (line 31 of \cref{lst_t4t:mtasktemp}
 \section{Could tierless \IOT{} programming be more reliable than tiered?}%
 \label{sec_t4t:Discussion}
 
-
 This section investigates whether tierless languages make \gls{IOT} programming more reliable. Arguably the much smaller and simpler code base is inherently more understandable, and more likely to be correct. Here we explore specific language issues, namely those of preserving type safety, maintainability, failure management, and community support.
 
 \subsection{Type safety}%
 \label{sec_t4t:typesafety}
 Strong typing identifies errors early in the development cycle, and hence plays a crucial role in improving software quality. In consequence almost all modern languages provide strong typing, and encourage static typing to minimise runtime errors.
-% Phil: so widely known that a citation is unnecessary \citep{madsen1990strong}.
 That said, many distributed system components written in languages that primarily use static typing, like \gls{HASKELL} and Scala, use some dynamic typing, e.g.\ to ensure that the data arriving in a message has the anticipated type \citep{epstein2011towards,gupta2012akka}.
 
 In a typical tiered multi-language \gls{IOT} system the developer must integrate software in different languages with very different type systems, and potentially executing on different hardware. The challenges of maintaining type safety have long been recognised as a major component of the semantic friction in multi-language systems, e.g.\ \citet{ireland_classification_2009}.
 
 Even if the different languages used in two components are both strongly typed, they may attribute, often quite subtly, different types to a value. Such type errors can lead to runtime errors, or the application silently reporting erroneous data. Such errors can be hard to find. Automatic detection of such errors is sometimes possible, but requires an addition tool like Jinn \citep{Jinn,Furr2005}.
-%Such errors can be hard to debug, partly because there is very limited tool support for detecting them
-%Phil: another possible source to discuss  \citep{egyed1999automatically}
 
 \begin{lstPython}[caption={\Gls{PRS} loses type safety as a sensor node sends a {\tt\footnotesize double}, and the server stores a {\tt\footnotesize string}.},label={lst_t4t:float},morekeywords={message,enum,uint64,double}]
 message SensorData {
@@ -1150,7 +1133,7 @@ The downside of this direct control is that \gls{CWS} has to handle some excepti
 \Cref{table_t4t:languagecomparison} summarises the differences between the \gls{CLEAN} \gls{IOT} \gls{EDSL} and their host language.
 The restrictions imposed by a resource-constrained execution environment on the tierless \gls{IOT} language are relatively minor. Moreover the \gls{MTASK} programming abstraction is broadly compatible with \gls{ITASK}. As a simple example compare the \gls{ITASK} and \gls{MTASK} temperature sensors in \cref{lst_t4t:itaskTempFull,lst_t4t:mtasktemp}. As a more realistic example, the \gls{MTASK} based \gls{CWS} smart campus implementation is similar to the \gls{ITASK} based \gls{CRS}, and requires less than 10\% additional code: 166 \gls{SLOC} compared with 155 \gls{SLOC} (\cref{table_t4t:multi}).
 
-Even with these restrictions, \gls{MTASK} programming is at a far higher level of abstraction than almost all bare metal languages, e.g.\ BIT, PICBIT, PICOBIT and Microscheme. That is \gls{MTASK} provides a set of higher order task combinators, shared distributed data stores, \etc. (\cref{sec_t4t:mtasks}). Moreover, it seems that common sensor node programs are readily expressed using \gls{MTASK}. In addition to the \gls{CWTS} and \gls{CWS} systems outlined here, other case studies include Arduino examples as well as some bigger tasks \citep{koopman_task-based_2018,lubbers_writing_2023,lubbers_multitasking_2019}. We conclude that the programming of sensor tasks is well-supported by both \glspl{DSL}.
+Even with these restrictions, \gls{MTASK} programming is at a far higher level of abstraction than almost all bare metal languages, e.g.\ BIT, PICBIT, PICOBIT and Microscheme. That is \gls{MTASK} provides a set of higher order task combinators, shared distributed data stores, \etc. (\cref{sec_t4t:mtasks}). Moreover, it seems that common sensor node programs are readily expressed using \gls{MTASK}. In addition to the \gls{CWTS} and \gls{CWS} systems outlined here, other case studies include \gls{ARDUINO} examples as well as some bigger tasks \citep{koopman_task-based_2018,lubbers_writing_2023,lubbers_multitasking_2019}. We conclude that the programming of sensor tasks is well-supported by both \glspl{DSL}.
 
 \section{Conclusion}%
 \label{sec_t4t:Conclusion}
@@ -1169,7 +1152,7 @@ Our empirical results for \gls{IOT} systems are consistent with the benefits cla
 \end{enumerate*}
 
 We show that \emph{tierless languages have the potential to significantly improve the reliability of \gls{IOT} systems}. We illustrate how \gls{CLEAN} maintains type safety, contrasting this with a loss of type safety in \gls{PRS}.
-We illustrate higher order failure management in \cimtask{} in contrast to the \gls{PYTHON}-based failure management in \gls{PRS}. For maintainability a tiered approach makes replacing components easy, but refactoring within the components is far harder than in a tierless \gls{IOT} language. Again our findings are consistent with the simplied \textit{Code Maintenance} benefits claimed for tierless languages \citep{weisenburger2020survey}.
+We illustrate higher order failure management in \cimtask{} in contrast to the \gls{PYTHON}-based failure management in \gls{PRS}. For maintainability a tiered approach makes replacing components easy, but refactoring within the components is far harder than in a tierless \gls{IOT} language. Again our findings are consistent with the simplified \textit{Code Maintenance} benefits claimed for tierless languages \citep{weisenburger2020survey}.
 Finally, we contrast community support for the technologies (\cref{sec_t4t:Discussion}).
 
 We report \emph{the first comparison of a tierless \gls{IOT} codebase for resource-rich sensor nodes with one for resource-constrained sensor nodes}.