From: Mart Lubbers Date: Thu, 24 Nov 2022 11:50:51 +0000 (+0100) Subject: many updates X-Git-Url: https://git.martlubbers.net/?a=commitdiff_plain;h=7abb270258db436c7a6bbc5d798858163420ab9f;p=phd-thesis.git many updates --- diff --git a/appx/mtask_aux.tex b/appx/mtask_aux.tex index ffeb74e..fc43da7 100644 --- a/appx/mtask_aux.tex +++ b/appx/mtask_aux.tex @@ -131,6 +131,46 @@ class LEDMatrix v where LMDisplay :: (v LEDMatrix) -> MTask v () \end{lstClean} +\subsection{Connection types}\label{lst:connection_types} +\begin{lstClean}[caption={}] +:: TCPSettings = + { host :: String + //** host name + , port :: Int + //** port number + , pingTimeout :: ?Int + //** Require a ping signal every so many seconds + } +:: MQTTSettings = + { host :: String + //** Host name + , port :: Int + //** Port number + , mcuId :: String + //** Identifier for the device + , serverId :: String + //** Identifier for the server + , auth :: MQTTAuth + //** Authentication type + } +:: TTYSettings = { + devicePath :: String, + //* Path of the device, e.g. /dev/ttyACM0 + baudrate :: BaudRate, + //* Baudrate + bytesize :: ByteSize, + //* Parity + parity :: Parity, + //* stop2bits + stop2bits :: Bool, + //* xonxoff flow control + xonxoff :: Bool, + //* Time in seconds to wait after opening the devices. Set this to 2 if you want to connect to a borked arduino + sleepTime :: Int + } +\end{lstClean} + + \lstset{basicstyle=\tt} \input{subfilepostamble} \end{document} diff --git a/dsl/class.tex b/dsl/class.tex index e39a88e..cd5a0af 100644 --- a/dsl/class.tex +++ b/dsl/class.tex @@ -49,7 +49,7 @@ This paper shows how to apply the technique observed in tagless-final embedding The presented basic technique, christened \emph{classy deep embedding}, does not require advanced type system extensions to be used. However, it is suitable for type system extensions such as \glspl{GADT}. While this paper is written as a literate -\Gls{HASKELL}~\citep{peyton_jones_haskell_2003} program using some minor extensions provided by \gls{GHC}~\citep{ghc_team_ghc_2021}, the idea is applicable to other languages as well\footnotemark{}. +\Gls{HASKELL}~\citep{peyton_jones_haskell_2003} program using some minor extensions provided by \gls{GHC}~\citep{ghc_team_ghc_2021}, the idea is applicable to other languages as well\footnotemark. \footnotetext{Lubbers, M. (2021): Literate Haskell/lhs2\TeX{} source code of the paper ``Deep Embedding with Class'': TFP 2022.\ DANS.\ \url{https://doi.org/10.5281/zenodo.5081386}.} @@ -137,7 +137,7 @@ class Expr_t s where add_t :: s -> s -> s \end{lstHaskellLhstex} -Semantics become data types\footnotemark{} implementing these type classes, resulting in the following instance for the evaluator. +Semantics become data types implementing these type classes, resulting in the following instance for the evaluator\footnotemark. \footnotetext{% In this case \haskelllhstexinline{newtype}s are used instead of regular \haskelllhstexinline{data} declarations. A \haskelllhstexinline{newtype} is a special data type with a single constructor containing a single value only to which it is isomorphic. @@ -246,7 +246,7 @@ sub_2 :: Expr_2 -> Expr_2 -> Expr_2 sub_2 e1 e2 = Ext_2 (Sub_2 e1 e2) \end{lstHaskellLhstex} -In our example this means that the programmer can write\footnotemark{}: +In our example this means that the programmer can write\footnotemark: \footnotetext{% Backticks are used to use functions or constructors in an infix fashion~\citep[\citesection{4.3.3}]{peyton_jones_haskell_2003}. } diff --git a/dsl/first.tex b/dsl/first.tex index e269a22..4b508c5 100644 --- a/dsl/first.tex +++ b/dsl/first.tex @@ -74,7 +74,7 @@ infixl 6 +. The implementation of a view on the \gls{DSL} is achieved by implementing the type classes with the data type representing the view. In the case of our example \gls{DSL}, an interpreter accounting for failure may be implemented as an instance for the \haskellinline{Maybe} type. -The standard infix functor application and infix sequential application are used so that potential failure is abstracted away from.\footnotemark{} +The standard infix functor application and infix sequential application are used so that potential failure is abstracted away from\footnotemark. \begin{lrbox}{\LstBox} \begin{lstHaskell}[frame=] <$> :: (a -> b) -> f a -> f b @@ -113,7 +113,7 @@ instance Div Maybe where \subsection{Adding semantics} To add semantics to the \gls{DSL}, the existing classes are implemented with a novel data type representing the view on the \gls{DSL}. -First a data type representing the semantics is defined. In this case, the printer is kept very simple for brevity and just defined as a \haskellinline{newtype} of a string to store the printed representation.\footnotemark{} +First a data type representing the semantics is defined. In this case, the printer is kept very simple for brevity and just defined as a \haskellinline{newtype} of a string to store the printed representation\footnotemark. \footnotetext{% In this case a \haskellinline{newtype} is used instead of regular \haskellinline{data} declarations. \haskellinline{newtype}s are special data types only consisting a single constructor with one field to which the type is isomorphic. @@ -171,7 +171,7 @@ instance Function a Maybe where \end{lstHaskell} The given \haskellinline{Printer} type is not sufficient to implement the instances for the \haskellinline{Function} class, it must be possible to generate fresh function names. -After extending the \haskellinline{Printer} type to contain some sort of state to generate fresh function names and a \haskellinline{MonadWriter [String]}\footnotemark{} to streamline the output, we define an instance for every arity. +After extending the \haskellinline{Printer} type to contain some sort of state to generate fresh function names and a \haskellinline{MonadWriter [String]}\footnotemark\ to streamline the output, we define an instance for every arity. \begin{lrbox}{\LstBox} \begin{lstHaskell}[frame=] freshLabel :: Printer String @@ -208,7 +208,7 @@ Unfortunately, once lifted, it is not possible to do anything with values of the 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. -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. +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. \footnotetext{ For example: \haskellinline{data List a = Nil \| Cons \{hd :: a, tl :: List a\}} @@ -345,19 +345,19 @@ The \haskellinline{Info} type is an \gls{ADT} containing all the---known to the With the power of metaprogramming, we can generate the boilerplate code for our user-defined data types automatically at compile time. To generate the code required for the \gls{DSL}, we define the \haskellinline{genDSL} function. The type belonging to the name passed as an argument to this function is made available for the \gls{DSL} by generating the \haskellinline{typeDSL} class and view instances. -For the \haskellinline{List} type it is called as: \haskellinline{\$(genDSL ''List)}.\footnotemark{} +For the \haskellinline{List} type it is called as: \haskellinline{\$(genDSL ''List)}\footnotemark. \footnotetext{ \haskellinline{''} is used instead of \haskellinline{'} to instruct the compiler to look up the information for \haskellinline{List} as a type and not as a constructor. } The \haskellinline{genDSL} function is a regular function---though \gls{TH} requires that it is defined in a separate module---that has type: \haskellinline{Name -> Q [Dec]}, i.e.\ given a name, it produces a list of declarations in the \haskellinline{Q} monad. The \haskellinline{genDSL} function first reifies the name to retrieve the structural information. -If the name matches a type constructor containing a data type declaration, the structure of the type---the type variables, the type name and information about the constructors\footnotemark{}---are passed to the \haskellinline{genDSL'} function. +If the name matches a type constructor containing a data type declaration, the structure of the type---the type variables, the type name and information about the constructors\footnotemark---are passed to the \haskellinline{genDSL'} function. \footnotetext{ Defined as \haskellinline{type VarBangType = (Name, Bang, Type)} by \gls{TH}. } The \haskellinline{getConsName} function filters out unsupported data types such as \glspl{GADT} and makes sure that every field has a name. -For regular \glspl{ADT}, the \haskellinline{adtFieldName} function is used to generate a name for the constructor based on the indices of the fields\footnotemark{}. +For regular \glspl{ADT}, the \haskellinline{adtFieldName} function is used to generate a name for the constructor based on the indices of the fields\footnotemark. \footnotetext{ \haskellinline{adtFieldName :: Name -> Integer -> Name} } @@ -494,7 +494,7 @@ The interpreter is a view on the \gls{DSL} that immediately executes all operati Therefore, the constructor function can be implemented by lifting the actual constructor to the \haskellinline{Maybe} type using sequential application. I.e.\ for a constructor $C_k$ this results in the following constructor: \haskellinline{ck a0 ... am = pure Ck <*> a0 <*> ... <*> am}. To avoid accidental shadowing, fresh names for all the arguments are generated. -The \haskellinline{ifx} function is used as a shorthand for defining infix expressions.\footnotemark{} +The \haskellinline{ifx} function is used as a shorthand for defining infix expressions\footnotemark. \begin{lrbox}{\LstBox} \begin{lstHaskell}[frame=] ifx :: String -> Q Exp -> Q Exp -> Q Exp @@ -518,7 +518,7 @@ In the case of a deconstructor a function with two arguments is created: the obj To avoid accidental shadowing first fresh names for the arguments and fields are generated. Then, a function is created with the two arguments. First \haskellinline{d} is evaluated and bound to a host language function that deconstructs the constructor and passes the fields to \haskellinline{f}. -I.e.\ a deconstructor function $C_k$ is defined as: \haskellinline{unCk d f = d >>= \\(Ck a0 .. am)->f (pure a0) ... (pure am))}.\footnotemark{} +I.e.\ a deconstructor function $C_k$ is defined as: \haskellinline{unCk d f = d >>= \\(Ck a0 .. am)->f (pure a0) ... (pure am))}\footnotemark. \footnotetext{ The \haskellinline{nameBase :: Name -> String} function from the \gls{TH} library is used to convert a name to a string. } @@ -634,7 +634,7 @@ mkPredicate n = fun (predicateName n) [] \section{Pattern matching} It is possible to construct and deconstruct values from other \gls{DSL} expressions, and to perform tests on the constructor but with a clunky and unwieldy syntax. They have become first-class citizens in a grotesque way. -For example, given that we have some language constructs to denote failure and conditionals\footnotemark{}, writing a list summation function in our \gls{DSL} would be done as follows. +For example, given that we have some language constructs to denote failure and conditionals\footnotemark, writing a list summation function in our \gls{DSL} would be done as follows. For the sake of the argument we take a little shortcut here and assume that the interpretation of the \gls{DSL} supports lazy evaluation by using the host language as a metaprogramming language as well, allowing us to use functions in the host language to contstruct expressions in the \gls{DSL}. \begin{lrbox}{\LstBox} diff --git a/front/motto.tex b/front/motto.tex index b4e2cac..f721056 100644 --- a/front/motto.tex +++ b/front/motto.tex @@ -41,6 +41,12 @@ }{% H.M. (Dick) Bruna } +\epigraph{% + \ldots and writing can make things a bit more bearable. + A book, is a suicide postponed. +}{% + E.M. (Emil) Cioran +} \vspace*{\fill}% \end{document} diff --git a/front/titlepage.tex b/front/titlepage.tex index 0dc88e3..9bce0be 100644 --- a/front/titlepage.tex +++ b/front/titlepage.tex @@ -35,7 +35,7 @@ \vspace{0.5cm} - op donderdag 1 juni 2023\\ + op \\%\\donderdag 1 juni 2023\\ om 12:00 uur precies \vspace{0.5cm} @@ -57,7 +57,7 @@ \begin{itemize}[wide,label={},leftmargin=*,itemsep=\baselineskip] \item Promotor: \begin{itemize}[label={}] - \item prof.\ dr.\ dr.h.c.\ ir.\ M.J.\ (Rinus)\ Plasmeijer\todo{em.\ erbij of niet?} + \item prof.\ dr.\ dr.h.c.\ ir.\ M.J.\ (Rinus)\ Plasmeijer \end{itemize} \item Copromotoren: \begin{itemize}[label={}] @@ -66,11 +66,11 @@ \end{itemize} \item Manuscriptcommissie: \begin{itemize}[label={}] - \item prof.\ dr.\ S.B.\ (Sven-Bodo) Scholz - \item prof.\ dr.\ C.U.\ (Clemens) Grelck (Friedrich-Schiller-Universit\"at Jena) - \item prof.\ dr.\ G.K.\ (Gabrielle) Keller (Universiteit Utrecht) - \item prof.\ dr.\ M.\ (Mary) Sheeran (Chalmers University of Gothenburg)\todo{Chalmers Tekniska H\"ogskola?} - \item prof.\ dr.\ R.T.W.\ (Ralf) Hinze (Technische Universit\"at Kaiserslautern) + \item \ldots%prof.\ dr.\ S.B.\ (Sven-Bodo) Scholz + \item \ldots%prof.\ dr.\ C.U.\ (Clemens) Grelck (Friedrich-Schiller-Universit\"at Jena) + \item \ldots%prof.\ dr.\ G.K.\ (Gabrielle) Keller (Universiteit Utrecht) +% \item prof.\ dr.\ M.\ (Mary) Sheeran (Chalmers University of Gothenburg)\todo{Chalmers Tekniska H\"ogskola?} +% \item prof.\ dr.\ R.T.W.\ (Ralf) Hinze (Technische Universit\"at Kaiserslautern) \end{itemize} \end{itemize} @@ -78,9 +78,9 @@ \begin{itemize}[wide,label={},leftmargin=*,itemsep=\baselineskip] \item This research was partly funded by the Royal Netherlands Navy. - \item Printed by Drukkerij + \item %Printed by Drukkerij \item Typeset using \LaTeXe{} - \item ISBN:\ 111{-}11{-}11111{-}11{-}1 + \item ISBN:\ %111{-}11{-}11111{-}11{-}1 \item Copyright \copyright{} Mart Lubbers, 2023 \item \href{https://martlubbers.net}{martlubbers.net} \item \small This work is licensed under the Creative Commons Attribution-NoDerivatives 4.0 International License. diff --git a/glossaries.tex b/glossaries.tex index b378c46..8bbc23d 100644 --- a/glossaries.tex +++ b/glossaries.tex @@ -62,6 +62,10 @@ \myacronym{UOG}{UoG}{University of Glasgow} % Glossaries +\newglossaryentry{ABC}{% + name=ABC, + description={is \gls{CLEAN}'s intermediate graph-rewriting language}, +} \newglossaryentry{MTASK}{% name=mTask, description={is a \glsxtrshort{TOP} \glsxtrshort{EDSL} for microcontrollers integrated with the \gls{ITASK} system}, diff --git a/intro/intro.tex b/intro/intro.tex index 6e672ce..6854812 100644 --- a/intro/intro.tex +++ b/intro/intro.tex @@ -15,7 +15,7 @@ \end{itemize} \end{chapterabstract} -There are at least 13.4 billion devices connected to the internet at the time of writing.\footnote{\url{https://transformainsights.com/research/tam/market}, accessed on: \formatdate{13}{10}{2022}} +There are at least 13.4 billion devices connected to the internet at the time of writing\footnote{\url{https://transformainsights.com/research/tam/market}, accessed on: \formatdate{13}{10}{2022}}. Each and every one of those devices senses, acts, or otherwise interacts with people, other computers, and the environment surrounding us. Even though there is a substantial variety among these devices, they have one thing in common: they are all computers to some degree and hence require software to operate. @@ -38,15 +38,17 @@ This thesis describes the research carried out around taming these complex \gls{ \Gls{TOP} is an innovative tierless programming paradigm for programming multi-tier interactive systems using a single declarative specification of the work that needs to be done. By utilising advanced compiler technologies, much of the internals, communication, and interoperation of the multi-tiered applications is automatically generated. The result of this compilation is a ready-for-work application. -Unfortunately, because the abstraction level is so high, the hardware requirements are too excessive for a general purpose \gls{TOP} system to be suitable for the average edge device. +For example, the \gls{TOP} system \gls{ITASK} can be used to program all layers of a distributed web application from a single source. +Unfortunately, because the abstraction level is so high, the hardware requirements are too excessive for such systems to be suitable for the average edge device. This is where \glspl{DSL} are brought into play. \Glspl{DSL} are programming languages created with a specific domain in mind. Consequently, jargon does not have to be expressed in the language itself, but they can be built-in features. As a result, the hardware requirements can be drastically lower, even with high levels of abstraction. -Using \gls{MTASK}, a novel domain-specific \gls{TOP} \gls{DSL} fully integrated with \gls{ITASK}, all layers of the \gls{IOT} can be orchestrated from a single source. -\todo[inline]{uitbreiden} +To bridge the gap between the \gls{IOT} edge devices, the \gls{MTASK} \gls{DSL} is used. +\Gls{MTASK} is a novel programming language for programming \gls{IOT} edge devices using \gls{TOP}. +As it is integrated with \gls{ITASK}, it allows for all layers of an \gls{IOT} application to be programmed from a single source. \section{Reading guide} The thesis is structured as a purely functional rhapsody. @@ -54,7 +56,7 @@ On Wikipedia, a musical rhapsody is defined as follows \citep{wikipedia_contribu \begin{quote}\emph{% A \emph{rhapsody} in music is a one-movement work that is episodic yet integrated, free-flowing in structure, featuring a range of highly contrasted moods, colour, and tonality.} \end{quote} -The three episodes in this thesis are barded by the introduction and conclusion (\cref{chp:introduction,chp:conclusion}). +%The three episodes in this thesis are barded by the introduction and conclusion (\cref{chp:introduction,chp:conclusion}). \Cref{prt:dsl} is a paper-based---otherwise known as cumulative---episode providing insights in advanced \gls{DSL} embedding techniques for \gls{FP} languages. The chapters are readable independently. \Cref{prt:top} is a monograph showing \gls{MTASK}, a \gls{TOP} \gls{DSL} for the \gls{IOT}. @@ -64,8 +66,8 @@ The chapter is readable independently. The following sections provide background material on the \gls{IOT}, \glspl{DSL}, and \gls{TOP} after which a detailed overview of the contributions is presented. Text typeset as \texttt{teletype} represents source code. -Standalone source code listings are marked by the programming language used. -Specifically for the \gls{FP} language \gls{CLEAN}, a guide tailored to \gls{HASKELL} programmers is available in \cref{chp:clean_for_haskell_programmers}. +Standalone source code listings are marked by the programming language used, e.g.\ \gls{CLEAN}\footnotemark, \gls{HASKELL}, \gls{CPP}, \etc. +\footnotetext{\Cref{chp:clean_for_haskell_programmers} contains a guide for \gls{CLEAN} tailored to \gls{HASKELL} programmers.} \section{\texorpdfstring{\Glsxtrlong{IOT}}{Internet of things}}\label{sec:back_iot} The \gls{IOT} is growing rapidly and it is changing the way people and machines interact with the world. @@ -219,11 +221,13 @@ Firstly, edge devices can be seen as simple resources, thus accessed through the The second view is that edge devices contain miniature \gls{LSOC} systems in itself as well. In \gls{TOSD} the same can be applied. The individual components in the miniature systems, the tasks, the \glspl{SDS}, are connected to the main system. -\todo[inline]{Is deze \P{} duidelijk genoeg?} +%\todo[inline]{Is deze \P{} duidelijk genoeg?} \subsection{\texorpdfstring{\Gls{ITASK}}{ITask}} The concept of \gls{TOP} originated from the \gls{ITASK} framework, a declarative interactive systems language and \gls{TOP} engine for defining multi-user distributed web applications implemented as an \gls{EDSL} in the lazy pure \gls{FP} language \gls{CLEAN} \citep{plasmeijer_itasks:_2007,plasmeijer_task-oriented_2012}. From the structural properties of the data types, the entire user interface is automatically generated. +Browsers are powering \gls{ITASK}'s perception layer. +The framework is written using standard web techniques such as JavaScript, HTML, and CSS, \gls{ITASK} code running in the browser relies on an interpreter that operates on \gls{CLEAN}'s intermediate language \gls{ABC} \citep{staps_lazy_2019}. As an example, \cref{lst:enter_person,fig:enter_person} show the \gls{ITASK} code and the corresponding \gls{UI} for a simple task for entering information about a person and viewing the entered result after completion. From the data type definitions (\cref{lst:dt_fro,lst:dt_to}), using generic programming (\cref{lst:dt_derive}), the \glspl{UI} for the data types are automatically generated. @@ -252,8 +256,9 @@ enterPerson \end{lstClean} \subsection{\texorpdfstring{\Gls{MTASK}}{MTask}} -\todo[inline]{Describe problem with iTask for the IoT.} -This thesis uses \gls{ITASK} in conjunction with \gls{MTASK}, an innovative \gls{TOP} language designed for defining interactive systems for \gls{IOT} edge devices \citep{koopman_task-based_2018}. +\Gls{ITASK} seems an obvious candidate at first glance for extending \gls{TOP} to \gls{IOT} edge devices. +However, \gls{IOT} edge devices are in general not powerful enough to run or interpret \gls{CLEAN}\slash\gls{ABC} code, they just lack the processor speed and the memory. +To bridge this gap, \gls{MTASK} was developed, a \gls{TOP} system for \gls{IOT} edge devices that is integrated in \gls{ITASK} \citep{koopman_task-based_2018}. \Gls{ITASK} abstracts away from details such as user interfaces, data storage, client-side platforms, and persistent workflows. On the other hand, \gls{MTASK} offers abstractions for edge layer-specific details such as the heterogeneity of architectures, platforms, and frameworks; peripheral access; (multi) task scheduling; and lowering energy consumption. The \gls{MTASK} language is written in \gls{CLEAN} as a multi-view \gls{EDSL} and hence there are multiple interpretations possible. @@ -264,7 +269,6 @@ This feather-light domain-specific \gls{OS} is written in portable \gls{C} with \Gls{MTASK} is seamlessly integrated with \gls{ITASK}: \gls{MTASK} tasks are integrated in such a way that they function as \gls{ITASK} tasks, and \glspl{SDS} in on the device can tether an \gls{ITASK} \gls{SDS}. Using \gls{MTASK}, the programmer can define all layers of an \gls{IOT} system as a single declarative specification. -\todo[inline]{Is this example useful? I think it's too technical} \Cref{lst:intro_blink} shows an interactive \gls{MTASK}\slash{}\gls{ITASK} application for blinking \pgls{LED} on the microcontroller every user-specified interval. \Crefrange{lst:intro:itask_fro}{lst:intro:itask_to} show the \gls{ITASK} part. First \pgls{SDS} is defined to communicate the blinking interval, then the \gls{MTASK} is connected using \cleaninline{withDevice}. @@ -274,7 +278,6 @@ It has its own tasks, \glspl{SDS}, and \gls{UOD}. This task first defines \gls{GPIO} pin 13 to be of the output type (\cref{lst:intro:declarePin}), followed by lifting the \gls{ITASK} \gls{SDS} to an \gls{MTASK} \gls{SDS} (\cref{lst:intro:liftsds}). The main expression of the program calls the \cleaninline{blink} function with an initial state. This function on \crefrange{lst:intro:blink_fro}{lst:intro:blink_to} first reads the interval \gls{SDS}, waits the specified delay, writes the state to the \gls{GPIO} pin and calls itself recursively using the inverse of the state. -\todo[inline]{conclude} \begin{lstClean}[numbers=left,caption={\Gls{MTASK}\slash{}\gls{ITASK} interactive blinking.},label={lst:intro_blink}] interactiveBlink :: Task Int[+\label{lst:intro:itask_fro}+] @@ -301,8 +304,7 @@ For example, \textmu{}Task \citep{piers_task-oriented_2016}, a \gls{TOP} languag Some \gls{TOP} languages were created to solve a practical problem.Toppyt \citep{lijnse_toppyt_2022} is a general purpose \gls{TOP} language written in \gls{PYTHON} used to host frameworks for modelling C2 systems, and hTask \citep{lubbers_htask_2022}, a vessel for experimenting with asynchronous \glspl{SDS}. Finally there are \gls{TOP} languages with strong academic foundations. \Gls{TOPHAT} is a fully formally specified \gls{TOP} language designed to capture the essence of \gls{TOP} formally \citep{steenvoorden_tophat_2019}. -It is also possible to translate \gls{TOPHAT} code to \gls{ITASK} to piggyback on the \gls{TOP} engine it offers \citep[\citesection{G.3}]{steenvoorden_tophat_2022}. -\todo[inline]{uitbreiden met voorbeelden wat je er mee kunt} +Such a formal specification allows for symbolic execution, hint generation, but also the translation to \gls{ITASK} for actually performing the work\citep[\citesection{G.3}]{steenvoorden_tophat_2022}. \section{Contributions}\label{sec:contributions} This section provides a thorough overview of the relation to publications and the scientific contributions of the episodes and chapters. @@ -337,19 +339,19 @@ It provides a gentle introduction to all aspects of the \gls{MTASK} system and \ While the language was a lot different from later versions, the integration mechanism is still used in \gls{MTASK} today. % \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 in which we discussed and refined the ideas. - \item \emph{Multitasking on Microcontrollers using Task Oriented Programming} \citep{lubbers_multitasking_2019}.\footnote{% + \item \emph{Multitasking on Microcontrollers using Task Oriented Programming} \citep{lubbers_multitasking_2019}\footnote{% This work acknowledges the support of the ERASMUS+ project ``Focusing Education on Composability, Comprehensibility and Correctness of Working Software'', no. 2017--1--SK01--KA203--035402 - } + }. This paper is a short paper on the multitasking capabilities of \gls{MTASK} comparing it to traditional multitasking methods for \gls{ARDUINO}. % \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-Based Embedded Domain Specific Language for the Internet of Things} \citep{koopman_simulation_2018}.\footnotemark[\value{footnote}] + \item \emph{Simulation of a Task-Based Embedded Domain Specific Language for the Internet of Things} \citep{koopman_simulation_2018}\footnotemark[\value{footnote}]. These revised lecture notes are from 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. % \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_2019}.\footnotemark[\value{footnote}] + \item \emph{Writing Internet of Things Applications with Task Oriented Programming} \citep{lubbers_writing_2019}\footnotemark[\value{footnote}]. These revised lecture notes are from a course on programming in \gls{IOT} systems using \gls{MTASK} provided at the 2019 \gls{CEFP}\slash{}\gls{3COWS} summer school in Budapest, Hungary. % \paragraph{Contribution} @@ -366,8 +368,8 @@ It provides a gentle introduction to all aspects of the \gls{MTASK} system and \ % \paragraph{Contribution} % The research was carried out by \citet{crooijmans_reducing_2021} during his Master's thesis. % I did the daily supervision and helped with the research, Pieter Koopman was the formal supervisor and wrote most of the paper. - \item \emph{Green Computing for the Internet of Things} \citep{lubbers_green_2022}.\footnote{ - This work acknowledges the support of the Erasmus+ project ``SusTrainable---Promoting Sustainability as a Fundamental Driver in Software Development Training and Education'', no. 2020--1--PT01--KA203--078646} + \item \emph{Green Computing for the Internet of Things} \citep{lubbers_green_2022}\footnote{ + This work acknowledges the support of the Erasmus+ project ``SusTrainable---Promoting Sustainability as a Fundamental Driver in Software Development Training and Education'', no. 2020--1--PT01--KA203--078646}. These revised lecture notes are from a course on sustainable \gls{IOT} programming with \gls{MTASK} provided at the 2022 SusTrainable summer school in Rijeka, Croatia. @@ -384,7 +386,7 @@ The paper of which I am first author are solely written by me. \subsection{\nameref{prt:tvt}} \Cref{prt:tvt} is based on a journal paper that quantitatively and qualitatively compares traditional \gls{IOT} architectures with \gls{IOT} systems using \gls{TOP} and contains a single chapter. -This chapter is based on the journal paper: \emph{Could Tierless Programming Reduce IoT Development Grief?} \citep{lubbers_could_2022}.\footnote{This work is an extension of the conference article: \emph{Tiered versus Tierless IoT Stacks: Comparing Smart Campus Software Architectures} \citep{lubbers_tiered_2020}.\footnotemark{}} +This chapter is based on the journal paper: \emph{Could Tierless Programming Reduce IoT Development Grief?} \citep{lubbers_could_2022}\footnote{This work is an extension of the conference article: \emph{Tiered versus Tierless IoT Stacks: Comparing Smart Campus Software Architectures} \citep{lubbers_tiered_2020}\footnotemark.}. \footnotetext{This paper was partly funded by the 2019 Radboud-Glasgow Collaboration Fund.} It compares programming traditional tiered architectures to tierless architectures by showing a qualitative and a quantitative four-way comparison of a smart-campus application. diff --git a/other.bib b/other.bib index 19b806a..586d6be 100644 --- a/other.bib +++ b/other.bib @@ -1765,3 +1765,20 @@ Publisher: Association for Computing Machinery}, keywords = {Energy, Environment, IoT, Smart city, SpliTech2020, Sustainability}, pages = {122877}, } + +@inproceedings{staps_lazy_2019, + address = {New York, NY, USA}, + series = {{IFL} '19}, + title = {Lazy {Interworking} of {Compiled} and {Interpreted} {Code} for {Sandboxing} and {Distributed} {Systems}}, + isbn = {978-1-4503-7562-7}, + url = {https://doi.org/10.1145/3412932.3412941}, + doi = {10.1145/3412932.3412941}, + abstract = {More and more applications rely on the safe execution of code unknown at compile-time, for example in the implementation of web browsers and plugin systems. Furthermore, these applications usually require some form of communication between the added code and its embedder, and hence a communication channel must be set up in which values are serialized and deserialized. This paper shows that in a functional programming language we can solve these two problems at once, if we realize that the execution of extra code is nothing more than the deserialization of a value which happens to be a function. To demonstrate this, we describe the implementation of a serialization library for the language Clean, which internally uses an interpreter to evaluate added code in a separate, sandboxed environment. Remarkable is that despite the conceptual asymmetry between "host" and "interpreter", lazy interworking must be implemented in a highly symmetric fashion, much akin to distributed systems. The library interworks on a low level with the native Clean program, but has been implemented without any changes to the native runtime system. It can therefore easily be ported to other programming languages.We can use the same technique in the context of the web, where we want to be able to share possibly lazy values between a server and a client. In this case the interpreter runs in WebAssembly in the browser and communicates seamlessly with the server, written in Clean. We use this in the iTasks web framework to handle communication and offload computations to the client to reduce stress on the server-side. Previously, this framework cross-compiled the Clean source code to JavaScript and used JSON for communication. The interpreter has a more predictable and better performance, and integration is much simpler because it interworks on a lower level with the web server.}, + booktitle = {Proceedings of the 31st {Symposium} on {Implementation} and {Application} of {Functional} {Languages}}, + publisher = {Association for Computing Machinery}, + author = {Staps, Camil and van Groningen, John and Plasmeijer, Rinus}, + year = {2019}, + note = {event-place: Singapore, Singapore}, + keywords = {functional programming, interpreters, laziness, sandboxing, web-assembly}, + file = {Staps et al. - 2019 - Lazy Interworking of Compiled and Interpreted Code.pdf:/home/mrl/.local/share/zotero/storage/LGS69CH8/Staps et al. - 2019 - Lazy Interworking of Compiled and Interpreted Code.pdf:application/pdf}, +} diff --git a/preamble.tex b/preamble.tex index 965fc41..5e7d265 100644 --- a/preamble.tex +++ b/preamble.tex @@ -15,6 +15,7 @@ \usepackage{relsize} % \smaller command \usepackage{siunitx} % typeset units \usepackage{xcolor} % colors +\usepackage{fnpct} % footnotekerning \DeclareSIUnit\noop{\relax} \DeclareSIUnit\celcius{{}^{\circ}\kern-\scriptspace\mathsf{C}} \everymath{\it\/} @@ -238,7 +239,7 @@ \lstnewenvironment{lstArduino}[1][] {% \lstset{language={[Arduino]C++}, #1} - \renewcommand*{\lstlistingname}{Listing (\gls{ARDUINO})} + \renewcommand*{\lstlistingname}{Listing (\gls{CPP})} } {} \lstnewenvironment{lstHaskell}[1][] diff --git a/top/green.tex b/top/green.tex index 79843f2..89dc07b 100644 --- a/top/green.tex +++ b/top/green.tex @@ -300,7 +300,7 @@ devTask = The task combinator \cleaninline{rpeat} restarts the child task in the evaluation if the previous produced a stable result. However, in some cases it is desirable to postpone the restart of the child. For this, the \cleaninline{rpeatEvery} task is introduced which receives an extra argument, the refresh rate, as shown in \cref{lst:rpeatevery}. -Instead of immediately restarting the child once it yields a stable value, it checks whether the lower bound of the provided timing interval has passed since the start of the task.\footnotemark{} +Instead of immediately restarting the child once it yields a stable value, it checks whether the lower bound of the provided timing interval has passed since the start of the task\footnotemark. \footnotetext{In reality, it also compensates for time drift by taking into account the upper bound of the timing interval. If the task takes longer to stabilise than the upper bound of the timing interval, this upper bound is taken as the start of the task instead of the actual start.} diff --git a/top/int.tex b/top/int.tex index a1742fc..30e74a2 100644 --- a/top/int.tex +++ b/top/int.tex @@ -10,7 +10,7 @@ \begin{chapterabstract} This chapter shows the integration of \gls{MTASK} with \gls{ITASK} by showing: \begin{itemize} - \item an architectural overview of \gls{MTASK}; + \item an architectural overview \gls{MTASK} applications; \item on the interface for connecting devices; \item the interface for lifting \gls{MTASK} tasks to \gls{ITASK} tasks; \item and interface for lifting \gls{ITASK} \glspl{SDS} to \gls{MTASK} \glspl{SDS}. @@ -20,7 +20,7 @@ The \gls{MTASK} language is a multi-view \gls{DSL}, i.e.\ there are multiple interpretations possible for a single \gls{MTASK} term. Using the byte code compiler (\cleaninline{BCInterpret}) \gls{DSL} interpretation, \gls{MTASK} tasks can be fully integrated in \gls{ITASK}. They are executed as if they are regular \gls{ITASK} tasks and they communicate may access \glspl{SDS} from \gls{ITASK} as well. -\Gls{MTASK} devices contain a domain-specific \gls{OS} (\gls{RTS}) and are little \gls{TOP} engines in their own respect, being able to execute tasks. +\Gls{MTASK} devices contain a domain-specific \gls{OS} and are little \gls{TOP} engines in their own respect, being able to execute tasks. \Cref{fig:mtask_integration} shows the architectural layout of a typical \gls{IOT} system created with \gls{ITASK} and \gls{MTASK}. The entire system is written as a single \gls{CLEAN} specification where multiple tasks are executed at the same time. Tasks can access \glspl{SDS} according to many-to-many communication and multiple clients can work on the same task. @@ -35,15 +35,15 @@ Using \cleaninline{liftmTask}, \gls{MTASK} tasks are lifted to a device (see \cr \label{fig:mtask_integration} \end{figure} -\section{Devices}\label{sec:withdevice} +\section{Connecting edge devices}\label{sec:withdevice} When interpreted by the byte code compiler view, an \gls{MTASK} task produces a compiler. This compiler is exceuted at run time so that the resulting byte code can be sent to an edge device. All communication with this device happens through a so-called \emph{channels} \gls{SDS}. The channels contain three fields, a queue of messages that are received, a queue of messages to send and a stop flag. Every communication method that implements the \cleaninline{channelSync} class can provide the communication with an \gls{MTASK} device. -As of now, serial port communication, direct \gls{TCP} communication and \gls{MQTT} over \gls{TCP} are supported as communication providers. -The \cleaninline{withDevice} function transforms a communication provider and a task that does something with this device to an \gls{ITASK} task. -Internally, the task sets up the communication, exchanges specifications, executes the inner task while handling errors, and finally cleans up after closing. +As of now, serial port communication, direct \gls{TCP} communication and \gls{MQTT} over \gls{TCP} are supported as communication providers (see \cref{lst:connection_types}). +The \cleaninline{withDevice} function transforms such a communication provider and a task that does something with this device to an \gls{ITASK} task. +Internally, the task sets up the communication, exchanges specifications with the device, executes the inner task while handling errors, and finally cleans up after closing. \Cref{lst:mtask_device} shows the types and interface to connecting devices. \begin{lstClean}[label={lst:mtask_device},caption={Device communication interface in \gls{MTASK}.}] @@ -52,10 +52,48 @@ Internally, the task sets up the communication, exchanges specifications, execut class channelSync a :: a (Shared sds Channels) -> Task () | RWShared sds -withDevice :: a (MTDevice -> Task b) -> Task b | iTask b & channelSync, iTask a +withDevice :: a (MTDevice -> Task b) + -> Task b | iTask b & channelSync, iTask a \end{lstClean} -\section{Lifting tasks}\label{sec:liftmtask} +\subsection{Implementation} +The \cleaninline{MTDevice} abstract type is internally represented as three \gls{ITASK} \gls{SDS} that contain all the current information about the tasks. +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 lifted \gls{SDS} is updated on the device, a message is sent to the server. +This message is initially queued in the map to allow for asynchronous handling of multiple updates. +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} to create anonymous local \glspl{SDS}. +Then, it performs the following four tasks in parallel to monitor the edge device. +\begin{enumerate} + \item It synchronises the channels using the \cleaninline{channelSync} overloaded function. + Errors that occur here are converted to the proper \gls{MTASK} exception. + \item Watches the channels for the shutdown flag. + If the connection is lost with the device unexpectedly, an \gls{MTASK} exception is thrown. + \item Watches the channels for messages and processes them accordingly by changing the device information \gls{SDS} or adding the lifted \gls{SDS} updates to the corresponding \gls{SDS} update queue. + \item Sends a request for a specification. Once the specification is received, the device task is run. + The task value of this device task is then used as the task value of the \cleaninline{withDevice} task. +\end{enumerate} + +If at any stage an unrecoverable device error occurs, an \gls{ITASK} exception is thrown on the \cleaninline{withDevice} task. +This exception can be caught in order to device some kind of fail-safe mechanism. +For example, when a device fails, the tasks can be sent to another device. +\todo[inline]{Example of failsafe?} + +%withDevice spec deviceTask +% withShared newMap \sdsupdates-> +% withShared ([], [MTTSpecRequest], False) \channels-> +% withShared default \dev->parallel +% [ channelSync spec // unexpected disconnect +% , watchForShutdown // unexpected disconnect +% , watchChannels // process messages +% , waitForSpecification +% >>| deviceTask +% >>* [ifStable: issueShutdown] +% ] + +\section{Lifting \texorpdfstring{\gls{MTASK}}{mTask} tasks}\label{sec:liftmtask} Once the connection with the device is established, \gls{MTASK} tasks can be lifted to \gls{MTASK} tasks using the \cleaninline{liftmTask} family of functions (see \cref{lst:liftmtask}). Given an \gls{MTASK} task in the \cleaninline{BCInterpret} view and a device obtained from \cleaninline{withDevice}, an \gls{ITASK} task is returned. This \gls{ITASK} task tethers the \gls{MTASK} task that is executed on the microcontroller. @@ -65,18 +103,59 @@ Hence, when for example observing the task value, the actual task value from the liftmTask :: (Main (MTask BCInterpret u)) MTDevice -> Task u | iTask u \end{lstClean} -Under the hood, \cleaninline{liftmTask} compiler the \gls{MTASK} task to byte code, gathers the initial values for the lifted \glspl{SDS} and sends the data to the device. -Once acknowledged, the \gls{MTASK} task value and the \glspl{SDS} are monitored. -If the \gls{ITASK} server updates the value of a lifted \gls{SDS}, the appropriate message is sent to the \gls{MTASK} to notify it of the change. -Furthermore, the \gls{MTASK} device may update the \gls{SDS}, and in that case the message is picked up by the \cleaninline{liftmTask} task and the \gls{SDS} on the \gls{ITASK} server updated accordingly. +Under the hood, \cleaninline{liftmTask}: +\begin{itemize} + \item Generates a fresh task identifier for the device. + \item Compiles the task and fetches the values for the tethered \glspl{SDS}. + \item Sends the task to the device + \item Watches, in parallel: the tethered \glspl{SDS} in \gls{ITASK}, if they are updated, a message is sent to the device; the \gls{SDS} update queue, if there is a downstream update, the \gls{ITASK} \gls{SDS} it references is updated as well; and the task value. +\end{itemize} + +The task value of the \cleaninline{liftmTask} task is the task value of the task on the edge device. + +\section{Lifting \texorpdfstring{\gls{ITASK}}{iTask} \texorpdfstring{\glsxtrlongpl{SDS}}{shared data sources}}\label{sec:liftsds} +Lifting \gls{ITASK} \glspl{SDS} to \gls{MTASK} \glspl{SDS} is something that mostly happens at the compiler level using the \cleaninline{liftsds} function (see \cref{lst:mtask_itasksds}). +\Glspl{SDS} in \gls{MTASK} must always have an initial value. +For regular \gls{SDS} this value is given in the source code, for lifted \gls{ITASK} \glspl{SDS} this value is obtained by reading the values once just before sending the task to the edge device. +On the device itself, there is just one difference between lifted \glspl{SDS} and regular \glspl{SDS}: after changing \pgls{SDS}, a message is sent to the server containing this new value. +The \cleaninline{withDevice} task (see \cref{sec:withdevice}) receives and processes this message by writing to the \gls{ITASK} \gls{SDS}. +Tasks watching this \gls{SDS} get notified then through the normal notification mechanism of \gls{ITASK}. -\section{Lifting \texorpdfstring{\glsxtrlongpl{SDS}}{shared data sources}}\label{sec:liftsds} \begin{lstClean}[label={lst:mtask_itasksds},caption={Lifted \gls{ITASK} \glspl{SDS} in \gls{MTASK}.}] class liftsds v where liftsds :: ((v (Sds t)) -> In (Shared sds t) (Main (MTask v u))) -> Main (MTask v u) | RWShared sds \end{lstClean} +The compilation of the code and the serialisation of the data throws away all typing information. +\Cref{lst:mtask_itasksds_lens} shows a pseudocode implementation of \cleaninline{liftsds}. +\Glspl{SDS} are stored in the compiler state as a map from identifiers to either an initial value or an \cleaninline{MTLens}. +The \cleaninline{MTLens} is a type synonym for a \gls{SDS} that represents the typeless serialised value of the underlying \gls{SDS}. +Such a \gls{SDS} is created by using the \cleaninline{mapReadWriteError} which, given a pair of read and write functions with error handling, produces a \gls{SDS} with the lens embedded. +The read function transforms, the function that converts a typed value to a typeless serialised value, just applies the serialisation. +The write function, the function that, given the new serialised value and the old typed value, produces a new typed value tries do deserialise the value. + +First, in similar fashion to how functions are implemented, using fixed points, the \glspl{SDS} is + +% VimTeX: SynIgnore on +\begin{lstClean}[label={lst:mtask_itasksds_lens},caption={Lens applied to lifted \gls{ITASK} \glspl{SDS} in \gls{MTASK}.}] +instance liftsds BCInterpret where + liftsds def = {main = + let (t In e) = def (abort "liftsds: expression too strict") + in addSdsIfNotExist (Right $ lens t) + >>= \sdsi-> let (t In e) = def (pure (Sds sdsi)) + in e.main + } + where + lens :: ((Shared sds a) -> MTLens) | type, iTask a & RWShared sds + lens = mapReadWriteError + ( \r->Ok (fromString (toByteCode{|*|} r) + , \w r-> ?Just <$> iTasksDecode (toString w) + ) ?None +\end{lstClean} +% VimTeX: SynIgnore off + + \section{Conclusion} diff --git a/tvt/tvt.tex b/tvt/tvt.tex index bacd7d9..e6f3295 100644 --- a/tvt/tvt.tex +++ b/tvt/tvt.tex @@ -949,8 +949,8 @@ The exchange of data, user interface, and communication are all automatically ge Another reason that the tierless \gls{CLEAN} implementations are concise is because they use powerful higher order \gls{IOT} programming abstractions. For comprehensibility the simple temperature sensor from \cref{sec_t4t:mtasks} (\cref{lst_t4t:mtasktemp}) is used to compare the expressive power of \gls{CLEAN} and \gls{PYTHON}-based \gls{IOT} programming abstractions. -There are implementations for all four configurations: \gls{PRTS} (\gls{PYTHON} Raspberry Pi Temperature Sensor)\footnotemark, \gls{PWTS}\footnotemark[\value{footnote}] -\footnotetext{Lubbers, M.; Koopman, P.; Ramsingh, A.; Singer, J.; Trinder, P. (2021): Source code, line counts and memory stats for PRS, PWS, PRT and PWT.\ Zenodo.\ \href{https://doi.org/10.5281/zenodo.5081386}{10.5281/zenodo.5081386}.}, \gls{CRTS}\footnotemark{} and \gls{CWTS}.\footnotemark[\value{footnote}] +There are implementations for all four configurations: \gls{PRTS} (\gls{PYTHON} Raspberry Pi Temperature Sensor)\footnotemark, \gls{PWTS}\footnotemark[\value{footnote}], +\footnotetext{Lubbers, M.; Koopman, P.; Ramsingh, A.; Singer, J.; Trinder, P. (2021): Source code, line counts and memory stats for PRS, PWS, PRT and PWT.\ Zenodo.\ \href{https://doi.org/10.5281/zenodo.5081386}{10.5281/zenodo.5081386}.} \gls{CRTS}\footnotemark{} and \gls{CWTS}\footnotemark[\value{footnote}]. \footnotetext{Lubbers, M.; Koopman, P.; Ramsingh, A.; Singer, J.; Trinder, P. (2021): Source code, line counts and memory stats for CRS, CWS, CRTS and CWTS.\ Zenodo.\ \href{https://doi.org/10.5281/zenodo.5040754}{10.5281/zenodo.5040754}.} but as the programming abstractions are broadly similar, we compare only the \gls{PWTS} and \gls{CWTS} implementations.