From 066dd25d4da01798ce7a5dd2c96e47040fa908d8 Mon Sep 17 00:00:00 2001 From: Mart Lubbers Date: Mon, 9 Jan 2023 14:45:10 +0100 Subject: [PATCH] . --- asbook.tex | 3 +- back/acknowledgements.tex | 80 +++++++++++++----- back/research_data_management.tex | 8 +- back/samenvatting.tex | 6 +- back/summary.tex | 17 +++- concl/concl.tex | 73 +---------------- dsl/class.tex | 4 +- dsl/first.tex | 1 - intro/intro.tex | 131 +++++++++++++++++------------- intro/lst/blink.icl | 2 +- intro/lst/sharedlist.icl | 2 +- intro/taskvalue.tex | 6 +- other.bib | 23 ++++++ preamble.tex | 5 +- self.bib | 52 ++++++------ thesis.tex | 4 +- top/4iot.tex | 93 +++++++++++++-------- top/finale.tex | 84 ++++++++++++++++--- top/green.tex | 10 ++- top/img/sim.png | Bin 0 -> 32340 bytes top/imp.tex | 11 ++- top/lang.tex | 128 +++++++++++++++++++++++++---- tvt/tvt.tex | 2 +- 23 files changed, 477 insertions(+), 268 deletions(-) create mode 100644 top/img/sim.png diff --git a/asbook.tex b/asbook.tex index f7228ca..a4a1cd7 100644 --- a/asbook.tex +++ b/asbook.tex @@ -4,5 +4,6 @@ \usepackage{pdfpages} \begin{document} -\includepdf[landscape,booklet,pages={1-18}]{thesis.pdf}%chktex 29 chktex 8 +%\includepdf[landscape,booklet,pages={1-18}]{thesis.pdf}%chktex 29 chktex 8 +\includepdf[landscape,booklet,pages={1-}]{top/4iot.pdf}%chktex 29 chktex 8 \end{document} diff --git a/back/acknowledgements.tex b/back/acknowledgements.tex index d2e862e..60fd5a1 100644 --- a/back/acknowledgements.tex +++ b/back/acknowledgements.tex @@ -7,31 +7,69 @@ \chapter{Acknowledgements}% \label{chp:acknowledgements} %\begin{center} -\noindent -Funding: Teun de Groot, Ton van Heusden +\noindent% +While the research and writing carried out for this thesis was mostly done by me, it could not have been done without the support of many others. -Supervisors: Pieter Koopman, Rinus Plasmeijer, Jan-Martin Jansen +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 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 Royal Dutch Navy, in particular Teun de Groot and Ton van Heusden, for trusting me by funding the project. +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: +Arjan Oortgiese, +Bas Lijnse, +Ellie Kimenai, +Fok Bolderheij, +Hans-Nikolai Vie\ss{}mann, +Ingrid Berenbroek, +John van Groningen, +Jurri\"en Stutterheim, +László Domoslai, +Marie-José van Diem, +Markus Klinik, +Peter Achten, +Ralf Hinze, +Simone Meeuwsen, +Sjaak Smetsers, +Steffen Michels, +Sven-Bodo Scholz, +Tim Steenvoorden. +% +The many students that allowed me to (co) supervise them in their theses: +Arjen Nederveen, +Colin de Roos, +Dave Artz, +Elina Antonova +Erin van der Veen, +Gijs Alberts, +Haye B\"ohm, +Matheus Amazonas Cabral de Andrade, +Michel de Boer, +Sjoerd Crooijmans, +Willem de Vos. -Co-authors: Jeremy Singer, Phil Trinder, Adrian Ramsingh, SusTrainable group +I give special thanks to my mentors who never stopped having faith me: +Jos Baack, Francisco Torreira, Franc Grootjen, Louis Vuurpijl, and Larry Caruthers. -%Colleagues: Jurriën Stutterheim, Laszlo Domoslai, Arjan Oortgiese, Bas Lijnse, Steffen Michels, Markus Klinik, Tim Steenvoorden, Camil Staps, Hans-Nikolai Vie\ss{}mann, John van Groningen, Sven-Bodo Scholz, Sjaak Smetsers, Fok Bolderheij, Simone Meeuwsen, Peter Achten, Ingrid Berenbroek -% -% -%\todo{Second assessor clients weglaten?: Willem, Dave, Gijs} -%Students: Matheus Amazonas Cabral de Andrade, Haye B\"ohm, Erin van der Veen, Colin de Roos, Willem de Vos, Michel de Boer, Dave Artz, Sjoerd Crooijmans, Gijs Alberts, Arjen Nederveen, Elina Antonova -% -%Mentors: Jos Baack, Francisco Torreira, Franc Grootjen, the late Louis Vuurpijl, Ralf Hinze -% -%Friends: Pieter Wolfert (and Annerieke Wessels (and Anouk Neerincx)); Chris Kamphuis and Maudy Bijen; Koen Dercksen and Michelle Everard; George Gregoire; Larry Caruthers; Tim Hirschler; Emma Lindahl (nee Dahl); Truman Crandell; -%\selectlanguage{russian} -%Александер Барков; -%\selectlanguage{british} -% -%Family: Parents (in law), brothers (in law), oma, -% -%Marie-José van Diem, Ellie Kimenai +And of course my friends and acquaintances that supported me throughout the procses. +Pieter Wolfert and Anouk Neerincx; +Chris Kamphuis and Maudy Bijen; +Koen Dercksen and Michelle Everard; +Jules Kruijswijk en Nadia Klijn; +George Gregoire; +\selectlanguage{russian}Александер Барков\selectlanguage{british}; +Tim Hirschler; +Emma Lindahl; +Truman Crandell; +Annerieke Wessels; +Camil Staps. + +Finally I want to thank the ones closest to me. +\selectlanguage{dutch} +Elvira, Rosalie en Liselotte voor hun tomeloze geduld en ondersteuning wanneer dat nodig was. +Mijn ouders in het bijzonder voor hun liefde en vertrouwen. +Mijn Oma, broers, schoonfamilie en alle andere familieleden die op wat voor manier dan ook bijgedragen hebben. +\selectlanguage{british} -Finally I want to thank all anonymous reviewers for the indispensable comments, suggestions and remarks on all papers. %\end{center} \input{subfilepostamble} \end{document} diff --git a/back/research_data_management.tex b/back/research_data_management.tex index e1ec602..db1d6d2 100644 --- a/back/research_data_management.tex +++ b/back/research_data_management.tex @@ -7,7 +7,7 @@ \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{\url{https://www.ru.nl/icis/research-data-management/}, last accessed \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 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} @@ -19,7 +19,7 @@ The following research datasets have been produced during this PhD research: \item \Fullref{sec:classy_reprise}: \begin{itemize} \item \rdmentry{\mlubbers}{2022} - {\todo[inline]{replace with actual name}} + {Library and examples for enhanced classy deep embedding} {Zenodo}{10.5281/zenodo.7277498} %chktex 8 \end{itemize} \end{itemize} @@ -29,7 +29,9 @@ The following research datasets have been produced during this PhD research: {Code for the paper ``First-Class Data Types in Shallow Embedded Domain-Specific Languages using Metaprogramming'': IFL 2022} {Zenodo}{10.5281/zenodo.6416747} \end{itemize} - \item \Fullref{prt:top}: + \item \Fullref{prt:top}:% + \todo{add set for green?}% + \todo{add set for sum\-mer school?}% \begin{itemize} \item \rdmentry{\mlubbers; \pkoopman; \rplasmeijer}{2020} {Source code for the mTask language} diff --git a/back/samenvatting.tex b/back/samenvatting.tex index aa9d1cf..8606084 100644 --- a/back/samenvatting.tex +++ b/back/samenvatting.tex @@ -7,13 +7,11 @@ \chapter{Samenvatting}% \label{chp:samenvatting} \selectlanguage{dutch} -\begin{center} - +%\begin{center} \noindent% Dit is een samenvatting van 350--400 woorden. -\end{center} - +%\end{center} \input{subfilepostamble} \selectlanguage{british} \end{document} diff --git a/back/summary.tex b/back/summary.tex index 08e0fd6..1f4a1a3 100644 --- a/back/summary.tex +++ b/back/summary.tex @@ -6,12 +6,21 @@ \input{subfileprefix} \chapter{Summary}% \label{chp:summary} -\begin{center} - +%\begin{center} \noindent% -This is a summary of 350--400 words. +The amount of computers around us is growing exponentially. +With it, the systems in which they operate are becoming more and more complex. +Many of these computers are so called \emph{edge devices}. +For a special class of systems, \glsxtrlong{IOT} systems, they perform the interaction with the world. +Powered by microcontrollers, these specialised computers have little memory, slow processors, and support slow communication methods. +On the other hand, they are also cheap, tiny, consume little energy, and can easily equipped with various sensors and actuators. -\end{center} +There is a great variety within edge devices but also between edge devices and more conventional computers. +However, they do have to communicate with the conventional computers. +This results in semantic friction, an impedance mismatch. +Developing and maintaining such systems is expensive and error prone. +This is a summary of 350--400 words. +%\end{center} \input{subfilepostamble} \end{document} diff --git a/concl/concl.tex b/concl/concl.tex index bc5cccf..57a0cd0 100644 --- a/concl/concl.tex +++ b/concl/concl.tex @@ -6,78 +6,7 @@ \input{subfileprefix} \chapter{Coda}% \label{chp:conclusion} -\section{Conclusion} - -\section{Future work} - -\section{Related work} -This section describes the related work. -The novelties of the \gls{MTASK} system can be compared to existing systems in several categories. -It is a tierless (\cref{sec:related_tierless}), 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}). -\todo{uit\-brei\-den waar mo\-ge\-lijk} - -\subsection{Interpretation}\label{sec:related_int} -There are a myriad of interpreted programming languages available for some of the bigger devices. -For example, for the popular ESP8266 chip there are ports of \gls{MICROPYTHON}, LUA, Basic, JavaScript and Lisp. -All of these languages, except the Lisp dialect uLisp (see \cref{ssec:related_fp}), are imperative and do not support multithreading out of the box. -They lay pretty hefty constraints on the memory and as a result do not work on smaller microcontrollers. -A interpretation solution for the tiniest devices is Firmata, a protocol for remotely controlling the microcontroller and using a server as the interpreter host \citep{steiner_firmata:_2009}. -\citet{grebe_haskino:_2016} wrapped this in a remote monad for integration with \gls{HASKELL} that allowed imperative code to be interpreted on the microprocessors. -Later this system was extended to support multithreading as well, stepping away from Firmata as the basis and using their own \gls{RTS} \citep{grebe_threading_2019}. -It differs from our approach because continuation points need to be defined by hand there is no automatic safe data communication. - -\subsubsection{\texorpdfstring{\Glsxtrlongpl{DSL}}{DSLs} for microcontrollers}\label{sec:related_dsl} -Many \glspl{DSL} provide higher-level programming abstractions for microcontrollers, for example providing strong typing or memory safety. -For example Copilot \citep{hess_arduino-copilot_2020} and Ivory \citep{elliott_guilt_2015} are imperative \glspl{DSL} embedded in a functional language that compile to \ccpp{}. - -\subsection{\texorpdfstring{\Glsxtrlong{FP}}{Functional programming}}\label{sec:related_fp} -\Citet{haenisch_case_2016} showed that there are major benefits to using functional languages for \gls{IOT} applications. -They showed 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 tiny 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. -More recently, \citep{suchocki_microscheme:_2015} created Microscheme, a functional language targeting \gls{ARDUINO} compatible microcontrollers. -The {*BIT} languages all compile to assembly while Microscheme compiles to \gls{CPP}, heavily supported by \gls{CPP} lambdas available even on \gls{ARDUINO} AVR targets. -An interpreted Lisp implementation called uLisp also exists that runs on microcontrollers with as small as the \gls{ARDUINO} {UNO} \citep{johnson-davies_lisp_2020}. - -\subsection{\texorpdfstring{\Glsxtrlong{FRP}}{Functional reactive programming}}\label{sec:related_frp} -The \gls{TOP} paradigm is often compared to \gls{FRP} and while they appear to be similar---they both process events---, in fact they are very different. -\Gls{FRP} was introduced by \citet{elliott_functional_1997}. -The paradigm strives to make modelling systems safer, more efficient, composable. -The core concepts are behaviours and events. -A behaviour is a value that varies over time. -Events are happenings in the real world and can trigger behaviours. -Events and behaviours may be combined using combinators. -\Gls{TOP} allows for more complex collaboration patterns than \gls{FRP} \citep{wang_maintaining_2018}, and in consequence is unable to provide the strong guarantees on memory usage available in a restricted variant of \gls{FRP} such as arrowized \gls{FRP} \citep{nilsson_functional_2002}. - -The way \gls{FRP}, and for that matter \gls{TOP}, systems are programmed stays close to the design when the domain matches suits the paradigm. -The \gls{IOT} domain seems to suit this style of programming very well in just the device layer\footnote{While a bit out of scope, it deserves mention that for \gls{SN}, \gls{FRP} and stream based approaches are popular as well \citep{sugihara_programming_2008}.} but also for entire \gls{IOT} systems. - -For example, Potato is an \gls{FRP} language for building entire \gls{IOT} systems using powerful devices such as the Raspberry Pi leveraging the Erlang \gls{VM} \citep{troyer_building_2018}. -It requires client devices to be able to run the Erlang \gls{VM} which makes it unsuitable for low memory environments. - -The emfrp language compiles a \gls{FRP} specification for a microcontroller to \gls{C} code \citep{sawada_emfrp:_2016}. -The \gls{IO} part, the bodies of some functions, still need to be implemented. -These \gls{IO} functions can then be used as signals and combined as in any \gls{FRP} language. -Due to the compilation to \gls{C} it is possible to run emfrp programs on tiny computers. -However, the tasks are not interpreted and there is no communication with a server. - -Other examples are mfrp \citep{sawada_emfrp:_2016}, CFRP \citep{suzuki_cfrp_2017}, XFRP \citep{10.1145/3281366.3281370}, Juniper \citep{helbling_juniper:_2016}, Hailstorm \citep{sarkar_hailstorm_2020}, Haski \citep{valliappan_towards_2020}, arduino-copilot~\cite{hess_arduino-copilot_2020}. - -\subsection{\texorpdfstring{\Glsxtrlong{TOP}}{Task-oriented programming}}\label{sec:related_top} -\Gls{TOP} as a paradigm with has been 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. -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 showed that applications tend to be able to cope well with interruptions and be more maintainable. -However, the hardware requirements for running the standard \gls{HASKELL} system are high. - -\subsection{Multi tasking}\label{sec:related_multi} - -\subsection{Tierless programming on microcontrollers}\label{sec:related_tierless} +\section{Reflection} \input{subfilepostamble} \end{document} diff --git a/dsl/class.tex b/dsl/class.tex index 41d0f75..d5d3467 100644 --- a/dsl/class.tex +++ b/dsl/class.tex @@ -8,7 +8,6 @@ \input{subfileprefix} \chapter{Deep embedding with class}% \label{chp:classy_deep_embedding} - \begin{chapterabstract} The two flavours of \gls{DSL} embedding are shallow and deep embedding. In functional languages, shallow embedding models the language constructs as functions in which the semantics are embedded. @@ -877,7 +876,8 @@ instance ( UsingExt '[e_1, e_2, ...] s, DependsOn '[i_1, i_2, ...] s) With these enhancements, there is hardly any boilerplate required to use classy deep embedding. The \haskelllhstexinline{Record} data type; the \haskelllhstexinline{CreateRecord} type class; and the \haskelllhstexinline{UsingExt} and \haskelllhstexinline{DependsOn} type families can be provided as a library only requiring the programmer to create the extension constructors with their respective implementations and smart constructors for language construct extensions. -The source code for this extension can be found here: \url{https://gitlab.com/mlubbers/classydeepembedding}. +The source code for this extension can be found here: \url{https://gitlab.com/mlubbers/classydeepembedding}.\footnote{Lubbers, M. (2022): Library and examples for enhanced classy deep embedding.\ Zenodo.\ \href{https://doi.org/10.5281/zenodo.7277498}{10.5281/zenodo.7277498}.} +It contains examples for expressions, expressions using \glspl{GADT}, detection of sharing in expressions (modelled after \citet{kiselyov_implementing_2011}), a \gls{GADT} version of sharing detection, and a region \gls{DSL} (modelled after \citet{sun_compositional_2022}). \section{Data types and definitions}% \label{sec:cde:appendix} diff --git a/dsl/first.tex b/dsl/first.tex index 67ca323..ad70ed3 100644 --- a/dsl/first.tex +++ b/dsl/first.tex @@ -8,7 +8,6 @@ \input{subfileprefix} \chapter{First-class data types in shallow \texorpdfstring{embedded domain-specific languages}{\glsxtrlongpl{EDSL}} using metaprogramming}% \label{chp:first-class_datatypes}% -%\chaptermark{First-class data types in shallow eDSLs using metaprogramming} \begin{chapterabstract} \Gls{FP} languages are excellent for hosting \glspl{EDSL} because of their rich type systems, minimal syntax, and referential transparency. However, data types defined in the host language are not automatically available in the embedded language. diff --git a/intro/intro.tex b/intro/intro.tex index 4e9d724..5e1453c 100644 --- a/intro/intro.tex +++ b/intro/intro.tex @@ -8,7 +8,7 @@ \chapter{Prelude}% \label{chp:introduction} \begin{chapterabstract} - This chapter introduces the dissertation and thesis by providing: + This chapter introduces the dissertation by providing: \begin{itemize} \item a general introduction to the topics and research venues; \item a reading guide; @@ -17,36 +17,40 @@ \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{\refurl{https://transformainsights.com/research/tam/market}{\formatdate{13}{10}{2022}}}. Each of these senses, acts, or otherwise interacts with people, other computers, and the environment surrounding us. Despite their immense diversity, they are all computers. And as computers, they require software to operate. An increasing amount of these connected devices are so-called \emph{edge devices} that operate in the \gls{IOT}. -Edge devices are the leafs of the \gls{IOT} systems, they perform the interaction with the physical world. +Edge devices are the leafs of the \gls{IOT} systems, they perform the interaction with the physical world and are physically embedded in the fabric. +They usually reside in hard-to-reach places such as light bulbs, smart electricity meters, or even farm animals. +Equipped with a lot of connectivity for integrating peripherals such as sensors and actuators, makes them very suitable to interact with their surroundings. Typically, these edge devices are powered by microcontrollers. -These miniature computers contain integrated circuits that accomodates a microprocessor designed for use in embedded applications. -Typically, microcontrollers are therefore tiny; have little memory; contain a slow, but energy-efficient processor; and allow for a lot of connectivity for integrating peripherals such as sensors and actuators in order to interact with their surroundings. +These miniature computers contain integrated circuits that accommodate a microprocessor designed for use in embedded applications. +Hence, microcontrollers are therefore cheap; tiny; have little memory; and contain a slow, but energy-efficient processor. Unlike the conductor in the orchestra waving their baton to instruct the ensemble of instruments, in the universe of software there is room for little error. +Moreover, in dynamic \gls{IOT} applications, often there is not even a conductor or coordinator. +Even though edge devices—the instruments—come and go, perform their own pieces, or are instructed to perform a certain piece, they operate without a central authority. In the traditional setting, an \gls{IOT} engineer has to program each device and their interoperation using different programming paradigms, programming languages, and abstraction levels. Thus resulting in semantic friction, making programming and maintaining \gls{IOT} systems is a complex and error-prone process. -This thesis describes the research carried out around orchestrating these complex \gls{IOT} systems using \gls{TOP}. +This dissertation describes the research carried out around orchestrating these complex \gls{IOT} systems using \gls{TOP}. \Gls{TOP} is an innovative tierless programming paradigm for interactive multi-layered systems. -By utilising advanced compiler technologies, much of the internals, communications, and interoperations between the tiers\slash{}layers of the applications is automatically generated. +By utilising advanced compiler technologies, much of the internals, communications, and interoperation between the tiers\slash{}layers of the applications is automatically generated. From a single declarative specification of the work required, the compiler makes a ready-for-work application consisting of interconnected components for all tiers. For example, the \gls{TOP} system \gls{ITASK} can be used to program all layers of a multi-user distributed web applications from a single source specification. -It is implemented in \gls{CLEAN} and executes also in \gls{CLEAN}'s run time. -The final executable is very low level and contains all these abstraction levels, this results in increased hardware requirements. +It is implemented in \gls{CLEAN}, executes also in \gls{CLEAN}'s general-purpose run time, and requires relatively powerful hardware. The high hardware requirements are no problem for regular computers but impractical for the average edge device. This is where \glspl{DSL} must be brought into play. +Using \glspl{DSL}, hardware requirements can be drastically lowered, even with high levels of abstraction for the specified domain. \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, hardware requirements can be drastically lowered, even with high levels of abstraction for the specified domain. +Furthermore, the \gls{DSL} can eschew language or system features that are irrelevant for the domain. -To incorporate the plethora of edge devices in the orchestra of an \gls{IOT} system, the \gls{MTASK} system is used. +To incorporate the plethora of edge devices in the orchestra of a \gls{TOP} system, the \gls{MTASK} system is used. \Gls{MTASK} is a novel programming language for programming \gls{IOT} edge devices using \gls{TOP}. Where \gls{ITASK} abstracts away from the gritty details of multi-tier web applications, \gls{MTASK} has domain-specific abstractions for \gls{IOT} edge devices, maintaining the high abstraction level that \gls{TOP} generally offers. As it is integrated with \gls{ITASK}, it allows for all layers of an \gls{IOT} application to be programmed from a single source. @@ -58,7 +62,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}). +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 are readable independently. \Cref{prt:top} is a monograph showing \gls{MTASK}, a \gls{TOP} \gls{DSL} for the \gls{IOT}. @@ -115,20 +119,22 @@ Even more so, the perception layer itself is often a heterogeneous collection of As edge hardware needs to be cheap, small-scale, and energy efficient, the microcontrollers used to power them do not have a lot of computational power, only a soup\c{c}on of memory, and little communication bandwidth. Typically, these devices are unable to run a full-fledged general-purpose \gls{OS}. Rather they employ compiled firmware written in imperative languages that combines all tasks on the device in a single program. -While devices are getting a bit faster, smaller, and cheaper, they keep these properties to an extent, greatly reducing the flexibility for dynamic systems when tasks are created on the fly, executed on demand, or require parallel execution. -As program memory is mostly flash-based and only lasts a couple of thousands of writes before it wears out, it is not suitable for rapid reconfiguring and reprogramming. +While devices are getting a bit faster, smaller, and cheaper, they keep these properties to an extent. +For example, more powerful microcontrollers are capable of running \gls{RTOS}, but this still requires many resources and fixes the programs at compile time. +As a consequence, the flexibility is greatly reduced for dynamic systems in which tasks are created on the fly, executed on demand, or require parallel execution. +As program memory is mostly flash-based and only lasts a couple of thousands of writes before it wears out, it is not suitable for repeated reconfiguring and reprogramming. These problems can be mitigated by dynamically sending code to be interpreted to the microcontroller. With interpretation, a specialized interpreter is flashed in the program memory once it receives the program code to execute at run time. Therefore, as the programs are not stored in the flash memory, it does not wear out. It is challenging to create interpreters for small edge devices due to the severe hardware restrictions. -However, the hardware requirements can be reduced by embedding domain-specific data into the langauge, so called \gls{DSL}; and the interpreter, a domain-specific \gls{OS}. +This dissertation describes a \gls{DSL} that encompasses the high-level programming concepts of \gls{TOP}, while it can be executed on edge devices with very limited requirements. +It does so by compiling the \gls{DSL} to byte code that is executed in a feather-light domain-specific \gls{OS}. \section{\texorpdfstring{\Glsxtrlongpl{DSL}}{Domain-specific languages}}% \label{sec:back_dsl} % General -Programming languages can be divided up into two categories: \glspl{DSL}\footnotemark\ and \glspl{GPL} \citep{fowler_domain_2010}. -\footnotetext{Historically \glsxtrshortpl{DSL} have been called DSELs as well.} +Programming languages can be divided up into two categories: \glspl{DSL} and \glspl{GPL} \citep{fowler_domain_2010}. Where \glspl{GPL} are not made with a demarcated area in mind, \glspl{DSL} are tailor-made for a specific domain. Writing idiomatic domain-specific code in a \gls{DSL} is easier and requires less background knowledge about a \gls{GPL}. This does come at the cost of the \gls{DSL} being sometimes less expressive to an extent that it may not even be Turing complete. @@ -136,7 +142,7 @@ This does come at the cost of the \gls{DSL} being sometimes less expressive to a Standalone languages are languages for which the complete toolchain has been developed, just as for any other \gls{GPL}. Embedded languages piggyback on an existing \gls{GPL}, they are defined in terms of their host language. \Glspl{EDSL} can further be classified into heterogeneous and homogeneous languages (\cref{sec:hetero_homo}). -In homogeneous languages all components are integrated whereas in heterogeneous \glspl{DSL}, some parts are ignorant of the other systems, e.g.\ a \gls{DSL} that generates code that is compiled by an existing compiler. +In homogeneous languages all components are integrated whereas in heterogeneous \glspl{DSL}, some parts are agnostic of the other systems, e.g.\ a \gls{DSL} that generates code for execution on a totally different system. This hyponymy is shown in \cref{fig:hyponymy_of_dsls}. \begin{figure} @@ -151,11 +157,11 @@ This hyponymy is shown in \cref{fig:hyponymy_of_dsls}. \glspl{DSL} where historically created as standalone languages, meaning that all machinery is developed solely for the language. The advantage of this approach is that the language designer is free to define the syntax and type system of the language as they wish, not being restricted by any constraint. Unfortunately it also means that they need to develop a compiler or interpreter, and all the scaffolding for the language, making standalone \glspl{DSL} costly to create. -Examples of standalone \glspl{DSL} are regular expressions, make, yacc, XML, SQL, \etc. +Examples of standalone \glspl{DSL} are \TeX, \LaTeX, make, yacc, XML, SQL, \etc. The dichotomous approach is embedding the \gls{DSL} in a host language, i.e.\ \glspl{EDSL} \citep{hudak_modular_1998}. By defining the language as constructs in the host language, much of the machinery is inherited \citep{krishnamurthi_linguistic_2001}. -This greatly reduces the cost of creating embedded languages. +This greatly reduces the cost of creating embedded languages and shields the user from having to learn a general-purpose language and toolchain. However, there are two sides to this coin. If the syntax of the host language is not very flexible, the syntax of the \gls{DSL} may become clumsy. Furthermore, \gls{DSL} errors shown to the programmer may be larded with host language errors, making it difficult for a non-expert of the host language to work with the \gls{DSL}. @@ -179,16 +185,15 @@ Examples of homogeneous \glspl{EDSL} are libraries such as ones for sets, region On the other hand, heterogeneous \glspl{EDSL} are languages that are not executed in the host language. For example, \citet{elliott_compiling_2003} describe the language Pan, for which the final representation in the host language is a compiler that will, when executed, generate code for a completely different target platform. In fact, \gls{ITASK} and \gls{MTASK} are embedded \glspl{DSL}. -\Gls{ITASK} runs in its host language as well, so it is a homogeneous \gls{DSL}. -Tasks written using \gls{MTASK} are dynamically compiled to byte code for an edge device and is therefore a heterogeneous \gls{DSL}. +Programs written in \gls{ITASK} run in the host language, and is a homogeneous \gls{DSL}. +Tasks written using \gls{MTASK} are dynamically compiled to byte code for an edge device, making it a heterogeneous \gls{DSL}. +The interpreter running on the edge device has no knowledge of the higher level task specification. +It just interprets the byte code it was sent, rewrites the tasks and publishes task values and \gls{SDS} updates. \section{\texorpdfstring{\Glsxtrlong{TOP}}{Task-oriented programming}}% \label{sec:back_top} \Gls{TOP} is a recent declarative programming paradigm for modelling interactive systems \citep{plasmeijer_task-oriented_2012}. -In \gls{TOP} languages, tasks are the basic building blocks. -They represent the actual work. -Instead of dividing problems into layers \gls{TOP} deals with separation of concerns in a novel way. -From the data types, utilising various \emph{type-parametrised} concepts, all other aspects are handled automatically (see \cref{fig:tosd}). +Instead of dividing problems into layers, \gls{TOP} deals with separation of concerns in a novel way. This approach to software development is called \gls{TOSD} \citep{wang_maintaining_2018}. \begin{figure} @@ -199,30 +204,35 @@ This approach to software development is called \gls{TOSD} \citep{wang_maintaini \end{figure} \begin{description} - \item[\Gls{UI}:] - The \gls{UI} of the system is automatically generated from the structural representation of the type. - Though, practical \gls{TOP} systems allow tweaking afterwards to suit the specific needs of the application. + \item[Types:] + As can be seen from \cref{fig:tosd}, types are the pivotal component in \gls{TOP}. + From the data types, utilising various \emph{type-parametrised} concepts, all other aspects are handled automatically. + Hence, all other components arise from and depend on the types in the program. \item[Tasks:] + In \gls{TOP} languages, tasks are the basic building blocks. A task is an abstract representation of a piece of work that needs to be done. It provides an intuitive abstraction over work in the real world. - Tasks are observable during execution. - It is possible to observe a---partial---result and act upon it, e.g.\ by starting new tasks. + The nature of tasks makes them observable during execution. + It is possible to observe a---partial---typed result and act upon it, e.g.\ taking the partial result as good enough, or by starting new tasks. Examples of tasks are filling forms, sending emails, reading sensors or even doing physical tasks. Just as with real-life tasks, multiple tasks can be combined in various ways such as in parallel or in sequence to form workflows. Such combination operators are called task combinators. \item[\Glspl{SDS}:] Tasks mainly communicate using their observable task values. - However, some collaboration requires tasks that are not necessarily related to share data. + However, some collaboration patterns are more easily expressed by tasks that share common data. \Glspl{SDS} fill this gap, they offer a safe abstraction over any data. - An \gls{SDS} can represent typed data stored in a file, a chunk of memory, a database \etc. + An \gls{SDS} can represent typed data stored in a file, a chunk of memory, a database, \etc. \Glspl{SDS} can also represent external impure data such as the time, random numbers or sensor data. - In many \gls{TOP} langauges, combinators are available to filter, combine, transform, and focus \glspl{SDS}. + In many \gls{TOP} languages, combinators are available to filter, combine, transform, and focus \glspl{SDS}. + \item[\Gls{UI}:] + The \gls{UI} of the system is automatically generated from the structural representation of the type. + Though, practical \gls{TOP} systems allow tweaking afterwards to suit the specific needs of the application. \item[\Gls{UOD}:] The \gls{UOD} is explicitly and separately modelled by the relations that exist in the functions of the host language. \end{description} \Cref{fig:tosd} differs from the presented \gls{IOT} architecture because they represent separate concepts. -The \gls{IOT} architecture from \cref{fig:iot-layers} describes an execution architecture wheras the \gls{TOSD} figure describes a softwared development model. +The \gls{IOT} architecture from \cref{fig:iot-layers} describes an execution architecture whereas the \gls{TOSD} figure describes a software development model. E.g.\ from a software development perspective, a task is a task, whether it is executed on a microcontroller, a server or a client. Only once a task is executed, the location of the execution becomes important, but this is taken care of by the system. Some concepts from the \gls{TOSD} model can be mapped upon the \gls{IOT} architecture though. @@ -230,22 +240,22 @@ Applying the concepts of \gls{TOSD} to \gls{IOT} systems can be done in two ways Firstly, edge devices can be seen as simple resources, thus accessed through \glspl{SDS}. The second view is that edge devices contain miniature \gls{TOP} systems in itself. The individual components in the miniature systems, the tasks, the \glspl{SDS}, are, in the eventual execution, connected to the main system. -\todo{ik ben niet echt te\-vre\-den met deze \P} \subsection{\texorpdfstring{\Gls{ITASK}}{ITask}} The concept of \gls{TOP} originated from the \gls{ITASK} framework, a declarative language and \gls{TOP} engine for defining interactive multi-user distributed web applications. \Gls{ITASK} is 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. +From the structural properties of the data types and the current status of the work to be done, the entire \gls{UI} is automatically generated. Browsers are powering \gls{ITASK}'s presentation layer. The framework is built on top of 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}. + Tasks in \gls{ITASK} have either \emph{no value}, an \emph{unstable} or a \emph{stable} task value. For example, an editor for filling in a form initially has no value. Once the user entered a complete value, its value becomes an unstable value, it can still be changed or even reverted to no value by emptying the editor again. -Only when for example a continue button is pressed, a task becomes stable, fixing its value. +Only when for example a continue button is pressed, a task value becomes stable, fixing its value. The allowed task value transitions are shown in \cref{fig:taskvalue}. -\begin{figure}[ht] +\begin{figure} \centering \includestandalone{taskvalue} \caption{Transition diagram for task values in \gls{ITASK}.}% @@ -255,6 +265,8 @@ The allowed task value transitions are shown in \cref{fig:taskvalue}. As an example, \cref{lst:todo,fig:todo} show the code and \gls{UI} for an interactive to-do list application. The user can modify a shared to-do list through an editor directly or using some predefined actions. Furthermore, in parallel, the length of the list is shown to demonstrate \glspl{SDS}. +Using \gls{ITASK}, complex collaborations of users and tasks can be described on a high level. + From the data type definitions (\cref{lst:todo_dt}), using generic programming (\cref{lst:todo_derive}), the \glspl{UI} for the data types are automatically generated. Then, using the parallel task combinator (\cleaninline{-\|\|}) that uses the left-hand side's result the task for updating the to-dos (\cref{lst:todo_update}) and the task for viewing the length are combined (\cref{lst:todo_length}). Both tasks operate on the to-do \gls{SDS} (\cref{lst:todo_sds}). @@ -262,6 +274,8 @@ The task for updating the to-do list is just an editor (\cref{lst:todo_editor}) The actions either change the value, sorting or clearing it, or terminates the task by returning the current value of the \gls{SDS}. Special combinators (e.g.\ \cleaninline{@>>} at \cref{lst:todo_ui}) are used to tweak the \gls{UI} to display informative labels. +\cleaninputlisting[float=,firstline=6,lastline=22,tabsize=3,numbers=left,caption={The code for the shared to-do list in \gls{ITASK}\footnotemark.},label={lst:todo}]{lst/sharedlist.icl} +\footnotetext{\Cref{chp:clean_for_haskell_programmers} contains a guide for \gls{CLEAN} tailored to \gls{HASKELL} programmers.} \begin{figure} \centering \includegraphics[width=.75\linewidth]{todo0g} @@ -269,28 +283,29 @@ Special combinators (e.g.\ \cleaninline{@>>} at \cref{lst:todo_ui}) are used to \label{fig:todo} \end{figure} -\cleaninputlisting[float=,firstline=6,lastline=22,tabsize=3,numbers=left,caption={The code for the shared to-do list in \gls{ITASK}\footnotemark.},label={lst:todo}]{lst/sharedlist.icl} -\footnotetext{\Cref{chp:clean_for_haskell_programmers} contains a guide for \gls{CLEAN} tailored to \gls{HASKELL} programmers.} - \subsection{\texorpdfstring{\Gls{MTASK}}{MTask}} -\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}. +The behaviour of \gls{IOT} edge devices can often be succinctly described by \gls{TOP} programs. +Software on microcontrollers is usually composed of smaller basic tasks, are interactive, and share data with other components or the server. +\Gls{ITASK} seems an obvious candidate at first glance for extending \gls{TOP} to \gls{IOT} edge device. +An \gls{ITASK} application contains many features that are not needed on \emph{edge devices} such as first-order tasks, support for a distributed architecture, or a multi-user web server. +Furthermore, \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 domain-specific \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. + +\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} 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. The \gls{MTASK} language is written in \gls{CLEAN} as a multi-view \gls{EDSL} and hence there are multiple interpretations possible. The byte code compiler is the most relevant for this thesis. From an \gls{MTASK} task constructed at run time, a compact binary representation of the work that needs to be done is compiled. This byte code is then sent to a device that running the \gls{MTASK} \gls{RTS}. This feather-light domain-specific \gls{OS} is written in portable \gls{C} with a minimal device specific interface and functions as a \gls{TOP} engine. -\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} 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. \Cref{lst:intro_blink,fig:intro_blink} shows the \gls{ITASK} part of the code and a screenshot of an interactive \imtask{} application for blinking \pgls{LED} on the microcontroller every dynamically changeable interval. Using \cleaninline{enterInformation}, the connection specification of the \gls{TCP} device is queried (\cref{lst:intro_enterDevice}). -\Cref{lst:intro_withshared} defines \pgls{SDS} to communicate the blinking interval. -Then the \gls{MTASK} is connected using \cleaninline{withDevice} at \cref{lst:intro_withdevice}. -Once connected, the \cleaninline{intBlink} task is sent to the device (\cref{lst:intro_liftmtask}) and, in parallel, an editor is shown that updates the value of the interval \gls{SDS} (\cref{lst:intro_editor}). +\Cref{lst:intro_withshared} defines \pgls{SDS} to communicate the blinking interval between the server and the edge device. +The \gls{MTASK} is connected using \cleaninline{withDevice} at \cref{lst:intro_withdevice}. +Once connected, the \cleaninline{intBlink} task is sent to the device (\cref{lst:intro_liftmtask}) and, in parallel, a web editor is shown that updates the value of the interval \gls{SDS} (\cref{lst:intro_editor}). To allow ending the task, the \gls{ITASK} task ends with a sequential operation that returns a constant value when the button is pressed, making the task stable. \cleaninputlisting[firstline=10,lastline=18,numbers=left,caption={The \gls{ITASK} code for the interactive blinking application.},label={lst:intro_blink}]{lst/blink.icl} @@ -323,11 +338,11 @@ intBlink :: (Shared sds Int) -> Main (MTask v Int) | mtask v & ...\end{lstClean} \subsection{Other \texorpdfstring{\glsxtrshort{TOP}}{TOP} languages} While \gls{ITASK} conceived \gls{TOP}, it is not the only \gls{TOP} system. -Some \gls{TOP} systems arose from Master's and Bachelor's thesis projects. -For example, \textmu{}Task \citep{piers_task-oriented_2016}, a \gls{TOP} language for modelling non-interruptible embedded systems in \gls{HASKELL}, and LTasks \citep{van_gemert_task_2022}, a \gls{TOP} language written in the dynamically typed programming language {LUA}. Some \gls{TOP} languages were created to fill a gap encountered in practise. Toppyt \citep{lijnse_toppyt_2022} is a general purpose \gls{TOP} language written in \gls{PYTHON} used to host frameworks for modelling \emph{Command\&Control} 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. +Furthermore, some \gls{TOP} systems arose from Master's and Bachelor's thesis projects. +For example, \textmu{}Task \citep{piers_task-oriented_2016}, a \gls{TOP} language for modelling non-interruptible embedded systems in \gls{HASKELL}, and LTasks \citep{van_gemert_task_2022}, a \gls{TOP} language written in the dynamically typed programming language {LUA}. +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}. Such a formal specification allows for symbolic execution, hint generation, but also the translation to \gls{ITASK} for actually performing the work \citep{steenvoorden_tophat_2022}. \Citeauthor{steenvoorden_tophat_2022} distinguishes two instruments for \gls{TOP}: \gls{TOP} languages and \gls{TOP} engines. @@ -352,7 +367,7 @@ This paper-based episode contains the following papers: \end{enumerate} \paragraph{Other publications on \texorpdfstring{\glspl{EDSL}}{eDSLs}:} -Furthermore, I co-authored another paper that is worth mentioning but is not part of the \gls{MTASK} system yet and hence not part of the dissertation. +Furthermore, I co-authored another paper that is not part of the \gls{MTASK} system yet and hence not part of the dissertation. \begin{enumerate}[resume] \item \emph{Strongly-Typed Multi-View Stack-Based Computations} \citep{koopman_strongly-typed_2022}\label{enum:stack-based} shows how to create type-safe \glspl{EDSL} representing stack-based computations. @@ -371,7 +386,7 @@ It is compiled from the following publications: \item \emph{A Task-Based \glsxtrshort{DSL} for Microcomputers} \citep{koopman_task-based_2018} is the initial \gls{TOP}\slash{}\gls{MTASK} paper. It provides an overview of the initial \gls{TOP} \gls{MTASK} language and shows first versions of some interpretations. - \item \emph{Task Oriented Programming for the Internet of Things} \citep{lubbers_task_2018}\footnotetext{This work is an extension of my Master's thesis \citep{lubbers_task_2017}.} + \item \emph{Task Oriented Programming for the Internet of Things} \citep{lubbers_task_2018}\footnotetext{This work is an extension of my Master's thesis \citeyearpar{lubbers_task_2017}.} shows how a simple imperative variant of \gls{MTASK} was integrated with \gls{ITASK}. While the language was a lot different from later versions, the integration mechanism is still used in \gls{MTASK} today. % \paragraph{Contribution} @@ -408,15 +423,15 @@ It is compiled from the following publications: \end{enumerate} \paragraph{Contribution:} -The original imperative predecessors, the \gls{MTASK} language, and their initial interpretations were developed by Pieter Koopman and Rinus Plasmeijer. -I continued with the language; developed the byte code interpreter, the precursor to the \gls{C} code generation interpretation; the integration with \gls{ITASK}; and the \gls{RTS}. +The original \gls{MTASK} language, and their initial interpretations were developed by Pieter Koopman and Rinus Plasmeijer. +I extended the language, developed the byte code interpreter, the integration with \gls{ITASK}, and the \gls{RTS}. The paper of which I am first author are solely written by me, there were weekly meetings with the co-authors in which we discussed and refined the ideas. \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 conference paper and a journal paper extending it: \begin{enumerate}[resume] - \item \emph{Tiered versus Tierless IoT Stacks: Comparing Smart Campus Software Architectures} \citep{lubbers_tiered_2020}\footnote{This work was partly funded by the 2019 Radboud-Glasgow Collaboration Fund.}\label{enum:iot20} compares traditional tiered programming to tierless architectures by comparing two implementations of a smart-campus application. + \item \emph{Tiered versus Tierless \glsxtrshort{IOT} Stacks: Comparing Smart Campus Software Architectures} \citep{lubbers_tiered_2020}\footnote{This work was partly funded by the 2019 Radboud-Glasgow Collaboration Fund.}\label{enum:iot20} compares traditional tiered programming to tierless architectures by comparing two implementations of a smart-campus application. \item \emph{Could Tierless Programming Reduce IoT Development Grief?} \citep{lubbers_could_2022} is an extended version of paper~\ref{enum:iot20}. It compares programming traditional tiered architectures to tierless architectures by illustrating a qualitative and a quantitative four-way comparison of a smart-campus application. diff --git a/intro/lst/blink.icl b/intro/lst/blink.icl index 2be0cdc..cc7fc5c 100644 --- a/intro/lst/blink.icl +++ b/intro/lst/blink.icl @@ -19,7 +19,7 @@ where enterDevice :: Task TCPSettings intBlink :: (Shared sds Int) -> Main (MTask v Int) | mtask, lowerSds v & RWShared sds & TC sds () Int Int -intBlink iInterval = declarePin D13 PMOutput \ledPin-> /*\label{lst:intro:declarePin}*/ +intBlink iInterval = declarePin D2 PMOutput \ledPin-> /*\label{lst:intro:declarePin}*/ lowerSds \mInterval=iInterval/*\label{lst:intro:liftsds}*/ In fun \blink=(\st-> /*\label{lst:intro:blink_fro}*/ getSds mInterval diff --git a/intro/lst/sharedlist.icl b/intro/lst/sharedlist.icl index 8b0e35c..b29e8be 100644 --- a/intro/lst/sharedlist.icl +++ b/intro/lst/sharedlist.icl @@ -15,7 +15,7 @@ toDoTask = upToDos/*\label{lst:todo_update}*/ upToDos :: Task [ToDo] upToDos = updateSharedInformation [] todos <<@ Title "My todo-list"/*\label{lst:todo_ui}\label{lst:todo_editor}*/ - >>* [ OnAction (Action "Sort") (hasValue \_->upd sort todos >-| upToDos)/*\label{lst:todo_ui}\label{lst:todo_contfro}*/ + >>* [ OnAction (Action "Sort") (hasValue \_->upd sort todos >-| upToDos)/*\label{lst:todo_contfro}*/ , OnAction (Action "Clear") (always (set [] todos >-| upToDos)) , OnAction (Action "Quit") (always (get todos))/*\label{lst:todo_ui}\label{lst:todo_contto}*/ ] diff --git a/intro/taskvalue.tex b/intro/taskvalue.tex index 039b0e7..05a3b50 100644 --- a/intro/taskvalue.tex +++ b/intro/taskvalue.tex @@ -1,14 +1,14 @@ \documentclass[tikz]{standalone} \usetikzlibrary{arrows.meta,shapes.symbols,matrix,positioning} \begin{document} - \begin{tikzpicture}[node distance=7em] - \node (1) {no value}; + \begin{tikzpicture}[node distance=7em,nodes={draw,minimum width=5em}] + \node (1) {no value}; \node (2) [right of=1] {unstable}; \node (3) [right of=2] {stable}; \draw [->] (1) -- (2); \draw [->] (2) -- (1); \draw [->] (2) -- (3); - \draw [->] (1) to [out=20,in=160] (3); + \draw [->] (1.north east) to [out=25,in=155] (3.north west); \end{tikzpicture} \end{document} diff --git a/other.bib b/other.bib index 64c17df..986ee40 100644 --- a/other.bib +++ b/other.bib @@ -1991,3 +1991,26 @@ Publisher: Association for Computing Machinery}, keywords = {IoT, Energy, Environment, Smart city, SpliTech2020, Sustainability}, pages = {122877}, } + +@inproceedings{santanna_safe_2013, + title = {Safe system-level concurrency on resource-constrained nodes}, + booktitle = {Proceedings of the 11th {ACM} {Conference} on {Embedded} {Networked} {Sensor} {Systems}}, + publisher = {ACM}, + author = {Sant'Anna, Francisco and Rodriguez, Noemi and Ierusalimschy, Roberto and Landsiedel, Olaf and Tsigas, Philippas}, + year = {2013}, + pages = {11}, + file = {Sant'Anna et al. - 2013 - Safe system-level concurrency on resource-constrai.pdf:/home/mrl/.local/share/zotero/storage/4865FAU3/Sant'Anna et al. - 2013 - Safe system-level concurrency on resource-constrai.pdf:application/pdf}, +} + +@article{kiselyov_implementing_2011, + title = {Implementing {Explicit} and {Finding} {Implicit} {Sharing} in {Embedded} {DSLs}}, + volume = {66}, + url = {https://doi.org/10.4204/eptcs.66.11}, + doi = {10.4204/eptcs.66.11}, + journal = {Electronic Proceedings in Theoretical Computer Science}, + author = {Kiselyov, Oleg}, + month = sep, + year = {2011}, + note = {Publisher: Open Publishing Association}, + pages = {210--225}, +} diff --git a/preamble.tex b/preamble.tex index 80bc930..afba2d2 100644 --- a/preamble.tex +++ b/preamble.tex @@ -16,6 +16,7 @@ \usepackage{siunitx} % typeset units \usepackage{xcolor} % colors \usepackage{fnpct} % footnotekerning +\usepackage[all]{nowidow} % Kill widows and orphans \DeclareSIUnit\noop{\relax} \DeclareSIUnit\celcius{{}^{\circ}\kern-\scriptspace\mathsf{C}} \everymath{\it\/} @@ -119,10 +120,9 @@ \makeatother \usepackage{framed} -%\newenvironment{chapterabstract}{\begin{quotation}\em\noindent}{\end{quotation}} %chktex 6 \definecolor{lstbg}{gray}{.95} \definecolor{shadecolor}{named}{lstbg} -\newenvironment{chapterabstract}{\begin{shaded}\em}{\end{shaded}} %chktex 6 +\newenvironment{chapterabstract}{\begin{shaded}\begin{quotation}}{\end{quotation}\end{shaded}} %chktex 6 % Increase the depth for the table of contents \setcounter{secnumdepth}{3} @@ -144,6 +144,7 @@ \usepackage{bibentry} % Cite bib entry completely \nobibliography* \newcommand{\citeentry}[1]{\begin{NoHyper}\bibentry{#1}\end{NoHyper}. \citep{#1}} +\newcommand{\refurl}[2]{\url{#1}, accessed on: #2} \makeatletter \newcommand{\citepage}[1]{p.~#1} diff --git a/self.bib b/self.bib index a662e88..1fc541e 100644 --- a/self.bib +++ b/self.bib @@ -26,7 +26,7 @@ publisher = {Springer International Publishing}, author = {Lubbers, Mart and Koopman, Pieter and Plasmeijer, Rinus}, year = {2019}, - note = {in-press}, + note = {in-press. preprint at: https://arxiv.org/abs/2212.04193}, pages = {51}, file = {cefp.pdf:/home/mrl/.local/share/zotero/storage/VEWFI5DG/cefp.pdf:application/pdf}, } @@ -153,17 +153,6 @@ file = {Koopman et al. - 2022 - SusTrainable Promoting Sustainability as a Fundam.pdf:/home/mrl/.local/share/zotero/storage/5F9SRJQI/Koopman et al. - 2022 - SusTrainable Promoting Sustainability as a Fundam.pdf:application/pdf}, } -@inproceedings{lubbers_deep_2022, - address = {Berlin, Heidelberg}, - title = {Deep {Embedding} with {Class}}, - booktitle = {Revised {Selected} {Papers} from the 23rd {International} {Symposium} on {Trends} in {Functional} {Programming}, {TFP} 2022, {Online}, 17-18 {March} 2022}, - publisher = {Springer Berlin Heidelberg}, - author = {Lubbers, Mart}, - year = {2022}, - note = {in-press}, - pages = {20}, -} - @inproceedings{lubbers_first-class_2022, address = {New York, NY, USA}, series = {{IFL} '22}, @@ -176,17 +165,6 @@ keywords = {clean, distributed applications, functional programming, internet of things, task oriented programming}, } -@inproceedings{crooijmans_reducing_2022, - address = {Berlin, Heidelberg}, - title = {Reducing the {Power} {Consumption} of {IoT} with {Task}-{Oriented} {Programming}}, - booktitle = {Revised {Selected} {Papers} from the 23rd {International} {Symposium} on {Trends} in {Functional} {Programming}, {TFP} 2022, {Online}, 17-18 {March} 2022}, - publisher = {Springer Berlin Heidelberg}, - author = {Crooijmans, Sjoerd and Lubbers, Mart and Koopman, Pieter}, - year = {2022}, - note = {in-press}, - pages = {20}, -} - @book{lubbers_orchestrating_2023, address = {Nijmegen}, title = {Orchestrating the {Internet} of {Things} using {Task}-{Oriented} {Programming}}, @@ -220,7 +198,7 @@ year = {2022}, note = {Place: New York, NY, USA Publisher: Association for Computing Machinery}, - keywords = {access control, internet-of-things, IoT stacks, policy language, privilege escalation, Smart home system, Tierless languages}, + keywords = {access control, internet-of-things, policy language, privilege escalation, Smart home system, IoT stacks, Tierless languages}, } @inproceedings{koopman_strongly-typed_2022, @@ -234,3 +212,29 @@ Publisher: Association for Computing Machinery}, note = {event-place: Kopenhagen, Denmark. under-review}, keywords = {clean, distributed applications, functional programming, internet of things, task oriented programming}, } + +@inproceedings{lubbers_deep_2022, + address = {Cham}, + title = {Deep {Embedding} with {Class}}, + isbn = {978-3-031-21314-4}, + abstract = {The two flavours of DSL embedding are shallow and deep embedding. In functional languages, shallow embedding models the language constructs as functions in which the semantics are embedded. Adding semantics is therefore cumbersome while adding constructs is a breeze. Upgrading the functions to type classes lifts this limitation to a certain extent.}, + booktitle = {Trends in {Functional} {Programming}}, + publisher = {Springer International Publishing}, + author = {Lubbers, Mart}, + editor = {Swierstra, Wouter and Wu, Nicolas}, + year = {2022}, + pages = {39--58}, +} + +@inproceedings{crooijmans_reducing_2022, + address = {Cham}, + title = {Reducing the {Power} {Consumption} of {IoT} with {Task}-{Oriented} {Programming}}, + isbn = {978-3-031-21314-4}, + abstract = {Limiting the energy consumption of IoT nodes is a hot topic in green computing. For battery-powered devices this necessity is obvious, but the enormous growth of the number of IoT nodes makes energy efficiency important for every node in the IoT. In this paper, we show how we can automatically compute execution intervals for our task-oriented programs for the IoT. These intervals offer the possibility to save energy by bringing the microprocessor driving the IoT node into a low-power sleep mode until the task need to be executed. Furthermore, they offer an elegant way to add interrupts to the system. We do allow an arbitrary number of tasks on the IoT nodes and achieve significant reductions of the energy consumption by bringing the microprocessor in sleep mode as much as possible. We have seen energy reductions of an order of magnitude without imposing any constraints on the tasks to be executed on the IoT nodes.}, + booktitle = {Trends in {Functional} {Programming}}, + publisher = {Springer International Publishing}, + author = {Crooijmans, Sjoerd and Lubbers, Mart and Koopman, Pieter}, + editor = {Swierstra, Wouter and Wu, Nicolas}, + year = {2022}, + pages = {80--99}, +} diff --git a/thesis.tex b/thesis.tex index b947f00..0759d45 100644 --- a/thesis.tex +++ b/thesis.tex @@ -68,7 +68,7 @@ \subfile{dsl/class} % Deep embedding with class \subfile{dsl/first} % First-class data types -\part{Orchestrating the Internet of Things using Task-Oriented Programming}% +\part[\hspace{-9pt}Orchestrating the Internet of Things using Task-Oriented Programming]{\\[2ex]\smaller{}Orchestrating the Internet of Things using Task-Oriented Programming}% \label{prt:top} \subfile{top/4iot} % TOP for the IoT \subfile{top/lang} % mTask DSL @@ -77,7 +77,7 @@ \subfile{top/green} % Green computing \subfile{top/finale} % Conclusion -\part{Tiered vs.\ Tierless Programming}% +\part[Tiered versus Tierless Programming]{\\[2ex]\smaller{}Tiered versus Tierless Programming}% \label{prt:tvt} \subfile{tvt/tvt} % Could Tierless Languages Reduce IoT Development Grief? diff --git a/top/4iot.tex b/top/4iot.tex index 429b8c9..fe9b520 100644 --- a/top/4iot.tex +++ b/top/4iot.tex @@ -9,17 +9,19 @@ \chapter{\texorpdfstring{\Glsxtrlong{TOP} for the \glsxtrlong{IOT}}{Task-oriented programming for the internet of things}}% \label{chp:top4iot} \begin{chapterabstract} - This chapter compares traditional edge device programming to \gls{TOP} by: + \noindent This chapter introduces the monograph. It compares traditional edge device programming to \gls{TOP} by: \begin{itemize} \item introducing edge device programming; \item showing how to create the \emph{Hello World!} application for microcontrollers using \gls{ARDUINO} and \gls{MTASK}; - \item extending the idea to multithreading, uncovering problems using \gls{ARDUINO}; - \item and demonstrating that upgrading to a multi-tasking variant is straightforward using \gls{MTASK}. + \item extending the idea to cooperative multitasking, uncovering problems using \gls{ARDUINO}; + \item demonstrating that upgrading to a multi-tasking variant is straightforward using \gls{MTASK}; + \item elaborating on integrating an edge device program with a server; + \item and providing a reading guide for the rest of the monograph. \end{itemize} \end{chapterabstract} The edge layer of \gls{IOT} systems predominantly consists of microcontrollers. -Microcontrollers are tiny computers designed specifically for embedded applications that much from regular computers in all aspects. +Microcontrollers are tiny computers designed specifically for embedded applications that differ much from regular computers in all aspects. They are much smaller; only have a fraction of the memory and processor speed; and run on different architectures. However, they have much more energy-efficient sleep modes, and support connecting and interfacing with peripherals such as sensors and actuators. \Cref{tbl:mcu_laptop} compares the hardware properties of a typical laptop with two very popular microcontrollers. @@ -38,40 +40,41 @@ Hence, all tasks must be manually combined into a single program. CPU speed & \qtyrange{2}{4}{\giga\hertz} & \qty{16}{\mega\hertz} & \qty{80}{\mega\hertz} or \qty{160}{\mega\hertz}\\ \textnumero{} cores & \numrange{4}{8} & 1 & 1\\ Storage & \qty{1}{\tebi\byte} & \qty{32}{\kibi\byte} & \qtyrange{0.5}{4}{\mebi\byte}\\ - \gls{RAM} & \qtyrange{4}{16}{\gibi\byte} & \qty{2}{\kibi\byte} & \qty{160}{\kibi\byte}\\ + \Gls{RAM} & \qtyrange{4}{16}{\gibi\byte} & \qty{2}{\kibi\byte} & \qty{160}{\kibi\byte}\\ Power & \qtyrange{50}{100}{\watt} & \qtyrange{0.13}{250}{\milli\watt} & \qtyrange{0.1}{350}{\milli\watt}\\ Size & $\pm$\qty{1060}{\cubic\cm} & $\pm$\qty{7.5}{\cubic\cm} & $\pm$\qty{1.1}{\cubic\cm}\\ + Display & \numproduct{1920x1080x24} & \numproduct{1x1x1} & \numproduct{1x1x1}\\ %chktex 29 Price & \euro{1500} & \euro{3} & \euro{4}\\ \bottomrule \end{tabular} \end{table} Different models of microcontrollers require their own vendor-provided drivers, hardware abstraction layer, compilers and \glspl{RTS}. -To structure this jungle of tools, platforms exist that provide abstraction layers over the low-level toolchains such as \gls{ARDUINO}. +To structure this jungle of tools, platforms exist that provide abstraction layers over the low-level toolchains such as \gls{ARDUINO}\footnote{\refurl{https://www.arduino.cc}{\formatdate{19}{12}{2022}}}. It is specifically designed for education and prototyping and hence used here to illustrate traditional microcontroller programming. The popular \gls{ARDUINO} \ccpp{} dialect and accompanying libraries provide an abstraction layer for common microcontroller behaviour allowing the programmer to program multiple types of microcontrollers using a single language. 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}. It provides an \gls{IDE} and toolchain automation to perform all steps of the toolchain with a single command. \section{\texorpdfstring{\Glsxtrshort{TOP} for the \glsxtrshort{IOT}}{TOP for the IoT}} -\Gls{TOP} is a programming paradigm that allows multi-tier interactive systems to be generated from a single declarative source. -\Gls{ITASK} is a general-purpose \gls{TOP} system for programming interactive distributed web applications. -These distributed web applications often form the core of the top two layers of \gls{IOT} applications. -Integrating the perception layer, the edge devices, in \gls{ITASK} also is not straightforward. -\Gls{ITASK} targets relatively fast but energy-hungry systems with large amounts of \gls{RAM} and a speedy connection. -Edge devices in \gls{IOT} systems are typically slow but energy efficient and do not have the memory to run the naturally heap-heavy functional programs that \gls{ITASK} programs are. -\Gls{MTASK} bridges this gap by providing a \gls{TOP} \gls{DSL} for \gls{IOT} edge devices. -Domain-specific knowledge is embedded in the language and execution platform, drastically lowering the hardware requirements. -The following sections compare traditional microcontroller programming with programming the devices using \gls{MTASK}. +\Gls{TOP} is a programming paradigm that allows multi-tier interactive systems to be generated from a single declarative source (see \cref{sec:back_top}). +An example of a \gls{TOP} system is \gls{ITASK}, a general-purpose \gls{TOP} language for programming interactive distributed web applications. +Interactive distributed web applications often form the core of the top two layers of \gls{IOT} applications. +Furthermore, \gls{IOT} edge devices are typically programmed with similar workflow-like programs for which \gls{TOP} is very suitable. +Directly incorporating the perception layer in \gls{ITASK} however is not straightforward. +\Gls{ITASK} targets relatively fast and hence energy-hungry systems with large amounts of \gls{RAM} and a speedy connection. +Edge devices in \gls{IOT} systems are typically slow but energy efficient and do not have the memory to run the naturally heap-heavy feature-packed functional programs that \gls{ITASK} programs are. +The \gls{MTASK} system bridges this gap by providing a \gls{TOP} \gls{DSL} 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 lowere the hardware requirements.\todo{beter?} \section{Hello world!} Traditionally, the first program that one writes when trying a new language is the so-called \emph{Hello World!} program. This program has the single task of printing the text \emph{Hello World!} to the screen and exiting again, useful to become familiarised with the syntax and verify that the toolchain and runtime environment is working. Microcontrollers usually do not come with screens in the traditional sense. -Nevertheless, almost always there is a built-in monochrome \numproduct{1x1} pixel screen, namely the built-in \gls{LED}. %chktex 29 +Nevertheless, almost always there is a built-in 1 pixel screen with a \qty{1}{\bit} color depth, namely the on-board \gls{LED}. The \emph{Hello World!} equivalent on microcontrollers blinks this \gls{LED}. -Using \gls{ARDUINO}'s \ccpp{} dialect to create the blink program results in the code seen in \citelisting{\ref{lst:arduinoBlink}}. +Using \gls{ARDUINO}'s \ccpp{} dialect to create the blink program results in the code seen in \cref{lst:arduinoBlink}. \Gls{ARDUINO} programs are implemented as cyclic executives and hence, each program defines a \arduinoinline{setup} and a \arduinoinline{loop} function. The \arduinoinline{setup} function is executed only once on boot, the \arduinoinline{loop} function is continuously called afterwards and contains the event loop. In the blink example, the \arduinoinline{setup} function only contains code for setting the \gls{GPIO} pin to the correct mode. @@ -91,24 +94,40 @@ void loop() { }\end{lstArduino} \subsection{Blinking the \texorpdfstring{\glsxtrshort{LED}}{LED} in \texorpdfstring{\gls{MTASK}}{mTask}.} -Naively translating the traditional blink program to \gls{MTASK} can be done by simply substituting some syntax as seen in \citelisting{\ref{lst:blinkImp}}. +Naively translating the traditional blink program to \gls{MTASK} can be done by simply substituting some syntax as seen in \cref{lst:blinkImp}. E.g.\ \arduinoinline{digitalWrite} becomes \cleaninline{writeD}, literals are prefixed with \cleaninline{lit} and the pin to blink is changed to represent the actual pin for the builtin \gls{LED} of the device used in the exercises. In contrast to the imperative \gls{CPP} dialect, \gls{MTASK} is a \gls{TOP} language and therefore there is no such thing as a loop, only task combinators to combine tasks. To simulate a loop, the \cleaninline{rpeat} task combinator can be used as this task combinator executes the argument task and, when stable, reinstates it. The body of the \cleaninline{rpeat} contains similarly named tasks to write to the pins and to wait in between. The tasks are connected using the sequential \cleaninline{>>|.} combinator that for all current intents and purposes executes the tasks after each other. -\begin{lstClean}[caption={Blinking the \gls{LED}.},label={lst:blinkImp}] -blink :: Main (MTask v ()) | mtask v -blink = - declarePin D2 PMOutput \d2-> + +\begin{lstClean}[caption={Blinking the \gls{LED} using the \cleaninline{rpeat} combinator.},label={lst:blinkImp}] +blinkTask :: Main (MTask v ()) | mtask v +blinkTask = declarePin D2 PMOutput \ledPin-> {main = rpeat ( - writeD d2 true + writeD ledPin true >>|. delay (lit 500) - >>|. writeD d2 false + >>|. writeD ledPin false >>|. delay (lit 500)) } \end{lstClean} +However, as \gls{MTASK} is hosted in a full fledged functional language, it is also possible to define the blinking behaviour as a function. +\Cref{lst:blinkFun} shows this more natural translation. +The \cleaninline{main} expression is just a call to the \cleaninline{blink} function parametrised with the state. +The \cleaninline{blink} function first writes the current state to the \gls{LED}, waits for the specific time and calls itself recursively with the inverse of the state, resulting in the same behaviour. +Creating recursive functions like this is not possible in the \gls{ARDUINO} language because the program would run out of stack quickly and combining multiple tasks defined this would be very difficult. + +\begin{lstClean}[caption={Blinking the \gls{LED} using a function.},label={lst:blinkFun}] +blinkTask :: Main (MTask v ()) | mtask v +blinkTask = declarePin D2 PMOutput \ledPin-> + fun \blink=(\st-> + writeD ledPin st + >>|. delay (lit 500) + >>|. blink (Not st)) + In {main = blink true} +\end{lstClean} + \section{Multi tasking} Now say that we want to blink multiple blinking patterns on different \glspl{LED} concurrently. For example, blink three \glspl{LED} connected to \gls{GPIO} pins $1,2$ and $3$ at intervals of \qtylist{500;300;800}{\ms}. @@ -145,9 +164,11 @@ In the simple case of blinking three \glspl{LED} according to fixed intervals, i Unfortunately, this is very hard when for example the blinking patterns are determined at runtime. \begin{lstArduino}[label={lst:blinkthread},caption={Threading three blinking patterns.}] -long led1 = 0, led2 = 0, led3 = 0; +long led1 = 0, led2 = 0, led3 = 0; bool st1 = false, st2 = false, st3 = false; +void setup () { ... } + void blink(int pin, int interval, long *lastrun, bool *st) { if (millis() - *lastrun > interval) { digitalWrite(pin, *st = !*st); @@ -166,37 +187,41 @@ In contrast to the \arduinoinline{delay} function in \gls{ARDUINO}, \gls{MTASK}' It has no observable value until the target waiting time has passed, and thence is \emph{stable}. To make code reuse possible and make the implementation more intuitive, the blinking behaviour is lifted to a recursive function instead of using the imperatively looking \cleaninline{rpeat} task combinator. There is no global state, the function is parametrized with the current status, the pin to blink and the waiting time. -Creating recursive functions like this is not possible in the \gls{ARDUINO} language because the program would run out of stack in an instant and nothing can be interleaved. With a parallel combinator, tasks are executed in an interleaved fashion. Therefore, blinking three different blinking patterns is as simple as combining the three calls to the \cleaninline{blink} function with their arguments as seen in \cref{lst:blinkthreadmtask}. % VimTeX: SynIgnore on \begin{lstClean}[label={lst:blinkthreadmtask},caption={Threading three blinking patterns.}] blinktask :: MTask v () | mtask v -blinktask = - declarePin D1 PMOutput \d1-> +blinktask = declarePin D1 PMOutput \d1-> declarePin D2 PMOutput \d2-> declarePin D3 PMOutput \d3-> fun \blink=(\(st, pin, wait)-> delay wait >>|. writeD d13 st >>|. blink (Not st, pin, wait)) - In {main = - blink (true, d1, lit 500) - .||. blink (true, d2, lit 300) - .||. blink (true, d3, lit 800) + In {main = blink (true, d1, lit 500) + .||. blink (true, d2, lit 300) + .||. blink (true, d3, lit 800) } \end{lstClean} % VimTeX: SynIgnore off -\section{Conclusion} +\section{Conclusion and reading guide} 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, and complex; and requires a lot of boilerplate and manual scheduling code. With the \gls{MTASK} system, a \gls{TOP} programming language for \gls{IOT} edge devices, this limitation can be overcome. As much domain-specific knowledge is built into the language and the \gls{RTS}, the hardware requirements can be kept relatively low while maintaining a high abstraction level. -\todo{moet dit uitgebreider?} +Furthermore, the programs are automatically integrated with \gls{ITASK}, allowing for data sharing, task coordination, and dynamic construction of tasks. + +The following chapters thoroughly introduce all aspects of the \gls{MTASK} system. +First the language setup and interface is shown in \cref{chp:mtask_dsl}. +Then the interface for integrating \gls{MTASK} with \gls{ITASK} is provided in \cref{chp:integration_with_itask}. +\Cref{chp:implementation} provides the implementation of the \gls{DSL}, the compilation schemes, instruction set and details on the interpreter. +\Cref{chp:green_computing_mtask} explains all the green computing aspects of \gls{MTASK}, i.e.\ task scheduling and processor interrupts. +Finally, \cref{chp:finale} concludes, and shows related work together with a short history of \gls{MTASK}. \input{subfilepostamble} \end{document} diff --git a/top/finale.tex b/top/finale.tex index fcd11a4..1ae84ee 100644 --- a/top/finale.tex +++ b/top/finale.tex @@ -7,16 +7,33 @@ \chapter{Finale}% \label{chp:finale} \begin{chapterabstract} - This chapter wraps up the monograph by: + \noindent This chapter wraps up the monograph by means of: \begin{itemize} - \item providing a conclusion; + \item a conclusion; + \item an outlook on future work; \item an overview of the related work; - \item and giving a history of the \gls{MTASK} system. + \item and a history of the \gls{MTASK} system. \end{itemize} \end{chapterabstract} \section{Finale} -\todo[inline]{Conclusion} +The \gls{MTASK} system is a proof-of-concept system, though fully functioning, for integrating \gls{IOT} edge devices in \gls{TOP}. +In conjunction with \gls{ITASK}, it is possible to program all layers of the \gls{IOT} from a single declarative specification. + +\section{Future work} +The \gls{MTASK} systems is a proof-of-concept system for integrating \gls{IOT} edge devices. + +Edge computing + +Intermittent computing + +Formal semantics + +Automatic peripherals + +Different architectures (FPGA?) + +Mesh communication \section{Related work} The novelties of the \gls{MTASK} system can be compared to existing systems in several categories. @@ -83,6 +100,56 @@ They showed that applications tend to be able to cope well with interruptions an However, the hardware requirements for running the standard \gls{HASKELL} system are high. \subsection{Multi tasking}\label{sec:related_multi} +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}. +This results in hard to maintain, error prone and unscalable spaghetti code. + +There are many solutions to overcome this problem in imperative languages. + +If the host language is a functional language (e.g.\ the aforementioned scheme variants) multitasking can be achieved without this burden relatively easy using continuation style multiprocessing \citep{wand_continuation-based_1980}. +Writing in this style is complicated and converting an existing program in this continuation passing style results in relatively large programs. +Furthermore, there is no built-in thread-safe communication possible between the tasks. +A \gls{TOP} or \gls{FRP} based language benefits even more because the programmer is not required to explicitly define continuation points. + +Regular preemptive multithreading is too memory intensive for smaller microcontrollers and therefore not suitable. +Manual interleaving of imperative code can be automated to certain extents. +Solutions often require an \gls{RTOS}, have a high memory requirement, do not support local variables, no thread-safe shared memory, no composition or no events as described in \cref{tbl:multithreadingcompare}. +The table compares the solutions in the relevant categories with \gls{MTASK}. + +\begin{table}[ht] + \begin{threeparttable} + \caption{% + An overview of imperative multithreading solutions for tiny computers with their relevant characteristics. + The characteristics are: sequential execution, local variable support, parallel composition, deterministic execution, bounded execution and safe shared memory (adapted from \citet[p.\ 12]{santanna_safe_2013}). + }\label{tbl:multithreadingcompare} +% \begin{tabular}{lc>{\columncolor[gray]{0.95}}cc>{\columncolor[gray]{0.95}}cc>{\columncolor[gray]{0.95}}cc} + \small + \begin{tabular}{lccccccc} + \toprule + \multicolumn{2}{c}{Language} & \multicolumn{3}{c}{Complexity} & \multicolumn{3}{c}{Safety}\\ + \midrule + Name & Year & SeqCmp & LocVar & ParCmp & DetEx & BndEx & SafeMem\\ + \midrule + Preemptive & many & \CIRCLE{} & \CIRCLE{} & \Circle{} & \Circle{} & rt & \Circle{}\\ + nesC & 2003 & \Circle{} & \Circle{} & \Circle{} & \CIRCLE{} & async & \Circle{}\\ + OSM & 2005 & \Circle{} & \CIRCLE{} & \CIRCLE{} & \Circle{} & \Circle{} & \Circle{}\\ + Protothreads & 2006 & \CIRCLE{} & \Circle{} & \Circle{} & \CIRCLE{} & \Circle{} & \Circle{}\\ + TinyThreads & 2006 & \CIRCLE{} & \CIRCLE{} & \Circle{} & \CIRCLE{} & \Circle{} & \Circle{}\\ + Sol & 2007 & \CIRCLE{} & \CIRCLE{} & \CIRCLE{} & \CIRCLE{} & \Circle{} & \Circle{}\\ + FlowTask & 2011 & \CIRCLE{} & \CIRCLE{} & \Circle{} & \Circle{} & \Circle{} & \Circle{}\\ + Ocram & 2013 & \CIRCLE{} & \CIRCLE{} & \Circle{} & \CIRCLE{} & \Circle{} & \Circle{}\\ + C\'eu & 2013 & \CIRCLE{} & \CIRCLE{} & \CIRCLE{} & \CIRCLE{} & \CIRCLE{} & \CIRCLE{}\\ + \Gls{MTASK} & 2022 & \CIRCLE{} & \CIRCLE{} & \CIRCLE{} & \CIRCLE{} & \LEFTcircle{}\tnote{1} & \LEFTcircle{}\tnote{2}\\ + \bottomrule + \end{tabular} + \begin{tablenotes} + \item [1] Only for tasks, not for expressions. + \item [2] Using \glspl{SDS}. + \end{tablenotes} + \end{threeparttable} +\end{table} \section{History of \texorpdfstring{\gls{MTASK}}{mTask}} The development of \gls{MTASK} or its predecessors has been going on for almost seven years now though it really set off during my master's thesis. @@ -117,16 +184,13 @@ In 2019, the \gls{CEFP}\slash\gls{3COWS} summer school in Budapest, Hungary host In 2022, the SusTrainable summer school in Rijeka, Croatia hosted a course on developing greener \gls{IOT} applications using \gls{MTASK} as well \citep{lubbers_green_2022}. Several students worked on extending \gls{MTASK} with many useful features: \Citet{van_der_veen_mutable_2020} did preliminary work on a green computing analysis, built a simulator, and explored the possibilities for adding bounded datatypes; \citet{de_boer_secure_2020} investigated the possibilities for secure communication channels; \citeauthor{crooijmans_reducing_2021} \citeyearpar{crooijmans_reducing_2021,crooijmans_reducing_2022} added abstractions for low-power operation to \gls{MTASK} such as hardware interrupts and power efficient scheduling; and \citet{antonova_mtask_2022} defined a preliminary formal semantics for a subset of \gls{MTASK}. +In 2023, the SusTrainable summer school in Coimbra, Portugal will host a course on \gls{MTASK} as well. \subsection*{\texorpdfstring{\gls{MTASK}}{mTask} in practise} 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 quantitively and qualitatively compared to the original application that was developed using a traditional \gls{IOT} stack \citep{lubbers_tiered_2020}. +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} implementation to the mix as well. - -\section{Future work} -Plans for extensions and improvements include exploring integrating \gls{TINYML} into \gls{MTASK}; adding intermittent computing support to \gls{MTASK}; and extending the formal semantics to cover the entirety of the language. -In 2023, the SusTrainable summer school in Coimbra, Portugal will host a course on \gls{MTASK} as well. +Currently, power efficiency behaviour of traditional versus \gls{TOP} \gls{IOT} stacks is being compared as well adding a \gls{FREERTOS}, and an elixer/potato implementation to the mix as well. \input{subfilepostamble} \end{document} diff --git a/top/green.tex b/top/green.tex index 5064d7e..2ba1ffd 100644 --- a/top/green.tex +++ b/top/green.tex @@ -7,10 +7,12 @@ \chapter{Green computing with \texorpdfstring{\gls{MTASK}}{mTask}}% \label{chp:green_computing_mtask} \begin{chapterabstract} - This chapter demonstrate the energy saving features of \gls{MTASK}. - First it gives an overview of general green computing measures for edge devices. - Then \gls{MTASK}'s task scheduling is explained and it is shown how to customise it so suit the applications and energy needs. - Finally it shows how to use interrupts in \gls{MTASK} to reduce the need for polling. + \noindent This chapter demonstrate the energy saving features of \gls{MTASK} by + \begin{itemize} + \item giving an overview of general green computing measures for edge devices; + \item explaining \gls{MTASK}'s task scheduling, and it is shown how to customise it so suit the applications and energy needs; + \item showing how to use interrupts in \gls{MTASK} to reduce the need for polling. + \end{itemize} \end{chapterabstract} The edge layer of the \gls{IOT} contains small devices that sense and interact with the world and it is crucial to lower their energy consumption. diff --git a/top/img/sim.png b/top/img/sim.png new file mode 100644 index 0000000000000000000000000000000000000000..ed0aabd12dbf3c84d613703539c8d0d8064134e8 GIT binary patch literal 32340 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 v a | toString a +\end{lstClean} + +Providing an evaluator is straightforward as can be seen in the following listing. +The evaluator is just a box holding a value of the computation but could also be some monadic computation. + +\begin{lstClean} +:: Eval a = Eval a + +runEval :: (Eval a) -> a +runEval (Eval a) = a + +instance literals Eval where + lit a = Eval a +\end{lstClean} + +Extending our language with a printer happens by defining a new data type and providing instances for the type constructor classes. +The printer stores a printed representation and hence the type is just a phantom type. + +\begin{lstClean} +:: Printer a = Printer String + +runPrinter :: (Printer a) -> String +runPrinter (Printer a) = a + +instance literals Printer where + lit a = Printer (toString a) +\end{lstClean} + +Finally, adding language constructs happens by defining new type classes and giving implementations for some of the interpretations. +The following listing adds an addition construct to the language and shows implementations for the evaluator and printer. -\begin{description} - \item[Printer] +\begin{lstClean} +class addition v where + add :: v a -> v a -> v a | + a - This interpretation converts the expression to a string representation. - As the host language \gls{CLEAN} constructs the \gls{MTASK} expressions at run time, it can be useful to show the constructed expression. - \item[Simulator] +instance addition Eval where + add (Eval l) (Eval r) = Eval (l + r) - The simulator converts the expression to a ready-for-work \gls{ITASK} simulation in which the user can inspect and control the simulated peripherals and see the internal state of the tasks. - \item[Byte code compiler] +instance addition Printer where + add (Printer l) (Printer r) = Printer ("(" +++ l +++ "+" +++ r +++ ")") +\end{lstClean} + +Terms in our little toy language can be overloaded in their interpretation, they are just an interface. +For example, $1+5$ is written as \cleaninline{add (lit 1) (lit 5)} and has the type \cleaninline{v Int \| literals, addition v}. +\todo{hier nog uit\-leg\-gen hoe je meer\-de\-re in\-ter\-pre\-ta\-tions kunt ge\-brui\-ken?} + +\section{Interpretations} +This section describes all \gls{MTASK}'s interpretations. +Not all of these interpretations are necessarily \gls{TOP} engines, i.e.\ not all of the interpretations execute the terms/tasks. +Some may perform an analysis over the program or typeset the program so that a textual representation can be shown. + +\subsection{Pretty printer} +This interpretation converts the expression to a string representation. +As the host language \gls{CLEAN} constructs the \gls{MTASK} expressions at run time, it can be useful to show the constructed expression. +The only function exposed for this interpretation is the \cleaninline{showMain} (\cref{lst:showmain}) function. +It runs the pretty printer and returns a list of strings containing the pretty printed result as shown in \cref{lst:showexample}. +The pretty printing function does the best it can but obviously cannot reproduce the layout, curried functions and variable names. +This shortcoming is illustrated by the example application for blinking a single \gls{LED} using a function and currying in \cref{lst:showexample}. + +\begin{lstClean}[caption={The entrypoint for the pretty printing interpretation.},label={lst:showmain}] +:: Show a // from the mTask Show library +showMain :: (Main (Show a)) -> [String] | type a +\end{lstClean} + +\begin{lstClean}[caption={Pretty printing interpretation example.},label={lst:showexample}] +blinkTask :: Main (MTask v Bool) | mtask v +blinkTask = + fun \blink=(\state-> + writeD d13 state >>|. delay (lit 500) >>=. blink o Not + ) In {main = blink true} + +// output: +// fun f0 a1 = writeD(D13, a1) >>= \a2.(delay 1000) >>| (f0 (Not a1)) in (f0 True) +\end{lstClean} + +\subsection{Simulator} +The simulator converts the expression to a ready-for-work \gls{ITASK} simulation in which the user can inspect and control the simulated peripherals and see the internal state of the tasks. +The task resulting from the \cleaninline{simulate} function presents the user with an interactive simulation environment (see \cref{lst:simulatemain,fig:sim}). +From within the interactive application, tasks can be (partly) executed, peripheral states changed and \glspl{SDS} interacted with. + +\begin{lstClean}[caption={The entrypoint for the simulation interpretation.},label={lst:simulatemain}] +:: TraceTask a // from the mTask Show library +simulate :: (Main (TraceTask a)) -> [String] | type a +\end{lstClean} + +\begin{figure} + \centering + \includegraphics[width=\linewidth]{simg} + \caption{Simulator interface for the blink program.}\label{fig:sim} +\end{figure} - The compiler compiles the \gls{MTASK} program to a specialised byte code. - Using a handful of integration functions and tasks (see \cref{chp:integration_with_itask}), \gls{MTASK} tasks can be executed on microcontrollers and integrated in \gls{ITASK} as if they were regular \gls{ITASK} tasks. - Furthermore, with special language constructs, \glspl{SDS} can be shared between \gls{MTASK} and \gls{ITASK} programs. -\end{description} +\subsection{Byte code compiler} +The main interpretation of the \gls{MTASK} system is the byte code compiler. +With it, and a handful of integration functions and tasks, \gls{MTASK} tasks can be executed on microcontrollers and integrated in \gls{ITASK} as if they were regular \gls{ITASK} tasks. +Furthermore, with a special language construct, \glspl{SDS} can be shared between \gls{MTASK} and \gls{ITASK} programs as well. +This interface is explained thoroughly in \cref{chp:integration_with_itask}. When using the byte code compiler interpretation in conjunction with the \gls{ITASK} integration, \gls{MTASK} is a heterogeneous \gls{DSL}. -I.e.\ some components---e.g.\ the \gls{RTS} on the microcontroller---is largely unaware of the other components in the system, and it is executed on a completely different architecture. +I.e.\ some components---for example the \gls{RTS} on the microcontroller---is largely unaware of the other components in the system, and it is executed on a completely different architecture. The \gls{MTASK} language is an enriched simply-typed $\lambda$-calculus with support for some basic types, arithmetic operations, and function definition; and a task language (see \cref{sec:top}). \section{Types} diff --git a/tvt/tvt.tex b/tvt/tvt.tex index e861028..3360822 100644 --- a/tvt/tvt.tex +++ b/tvt/tvt.tex @@ -4,7 +4,7 @@ \begin{document} \input{subfileprefix} -\chapter{Could Tierless Languages Reduce IoT Development Grief?}% +\chapter{Could Tierless Languages Reduce \texorpdfstring{\glsxtrshort{IOT}}{IoT} Development Grief?}% \label{chp:smart_campus} \begin{chapterabstract} -- 2.20.1