\input{subfilepreamble}
\begin{document}
-\chapter{Prelude --- Introduction}%
+\chapter{Prelude}%
\label{chp:introduction}
-\begin{chapterabstract}
- \noindent%
- \begin{itemize}
- \item How many devices are there?
- \begin{itemize}
- \item Number of devices is big\footnote{\url{https://transformainsights.com/research/tam/market}, accessed on: \formatdate{2022}{10}{13}}
- \item It only grows
- \item they are powered by software
- \item These devices live in layered systems
- \end{itemize}
- \item What is the {IoT}?
- \begin{itemize}
- \item IoT is such a layered system
- \item Layers, device layer
- \end{itemize}
- \item What is impedance mismatch/semantic friction?
- \begin{itemize}
- \item heterogeneous between layers
- \item heterogeneous on the device/edge/perception layer
- \item Results in problems in software
- \item We see this also in web systems
- \end{itemize}
- \item What is TOP?\todo{hier al TOP uitleggen in \`e\`en zin? of alleen benoemen}
- \begin{itemize}
- \item declarative workflow language (partiture AND conductor)
- \item iTask for distributed web applications.
- \end{itemize}
- \item This thesis: how to orchestrate this concerto of devices?
- \begin{itemize}
- \item Embedded devices require special code (different clef/key)
- \item DSL is a special language in a language to facilitate this (part 1)
- \item mTask is a TOP language for IoT (part 2)
- \item This approach is called tierless programming (part 3)
- \end{itemize}
- \end{itemize}
-
- This chapter provides the required background material, an overview of the concrete contributions and a reading guide.
-
-% The sheer number of connected devices around us is mind boggling and seems increases exponentially for many years.
-% In 2022, there is an estimated number of 13.4 billion of devices connected that sense, act or otherwise interact with people and the physical world surrounding us\footnote{\url{https://transformainsights.com/research/tam/market}, accessed on: \formatdate{2022}{10}{13}}.
-% These devices, together with all the scaffolding and integration such as the various networks providing the communication, (cloud) computers realising the back end or administration and the devices in our pockets providing us with a view on the system are called the \gls{IOT}.
-% \Gls{IOT} systems can be seen as layered systems, where each layer is powered by different types of computers; programming languages and even programming paradigms.
-% This thesis shows a novel way of orchestrating these brobdingnagian systems using the \gls{TOP} paradigm.
-% It does so by giving a proof-of-concept implementation for a \gls{TOP} system specifically designed for the \gls{IOT}: \gls{MTASK}.
-% At the core of the \gls{MTASK} system is a \gls{DSL}, embedded in the general purpose \gls{TOP} system \gls{ITASK}.
-% Using the \gls{MTASK} system, all layers of an \gls{IOT} system can be programmed from a single declarative specification.
-
-\end{chapterabstract}
-
-\section{Internet of Things}
+In 2022, there were an estimated number of 13.4 billion of connected computers that sense, act or otherwise interact with people, other computers and the physical world surrounding us\footnotemark{}.
+\footnotetext{\url{https://transformainsights.com/research/tam/market}, accessed on: \formatdate{2022}{10}{13}}
+The variety among these devices is considerable but these devices have one thing in common though: they are all controlled by software.
+Concretely this means that programmers write code for these specific device to make sure the brains of the device---the processor---do what we want it to do.
+
+An increasing amount of these connected devices are so-called \emph{edge devices}.
+Typically these edge devices are small microprocessors containing various sensors and actuators to interact with the physical world.
+They are often part of and coordinated by a bigger system called \gls{IOT} systems.
+
+
+%These ed
+%These edge devices differ very much from other devices we see around us.
+%Compared to servers, laptops, tablets, or mobile phones they boast tiny amounts of memory, are powered by a slow but energy efficient microprocessor, only support low-level programming languages, and are not so easily reprogrammed.
+%Moreover, these edge devices differ among eachother as well by using various microprocessor architectures, different communication protocols and using a variety of device-specific toolchains.
+%As a result, there are many points of failure and programming these systems is difficult and error-prone.
+%
+%\Gls{TOP} is a novel programming paradigm that offers a solution to this problem.
+%In a \gls{TOP} language, from a single declarative specification of the work that needs to be done, ready-for-work applications are generated for all layers of the system.
+%However, the hardware requirements for traditional \gls{TOP} frameworks make it not feasable to run these generated applications on resource-constrained edge devices.
+%
+%\Glspl{DSL} can overcome this limitation because domain-specific knowledge is built into the programming language, allowing for lower hardware requirements.
+%This thesis presents \gls{MTASK}, a \gls{TOP} \gls{DSL} for edge devices that can be fully integrated with \gls{ITASK}, a \gls{TOP} \gls{DSL} for distributed multi-user workflow systems.
+%With \gls{MTASK}, all layers of an \gls{IOT} system can be programmed from a single programming language in a single programming paradigm.
+
+\section{Internet of things}\label{sec:back_iot}
The \gls{IOT} is growing rapidly and it is changing the way people and machines interact with the world.
-While the term \gls{IOT} briefly gained interest around 1999 to describe the communication of \gls{RFID} devices~\citep{ashton_internet_1999,ashton_that_2009}, it probably already popped up halfway the eigthies in a speech by \citet{peter_t_lewis_speech_1985}:
+While the term \gls{IOT} briefly gained interest around 1999 to describe the communication of \gls{RFID} devices \citep{ashton_internet_1999,ashton_that_2009}, it probably already popped up halfway the eighties in a speech by \citet{peter_t_lewis_speech_1985}:
\begin{quote}
\emph{The \glsxtrlong{IOT}, or \glsxtrshort{IOT}, is the integration of people, processes and technology with connectable devices and sensors to enable remote monitoring, status, manipulation and evaluation of trends of such devices.}
\end{quote}
-CISCO states that the \gls{IOT} only started when there where as many connected devices as there were people on the globe, i.e.\ around 2008~\citep{evans_internet_2011}.
+CISCO states that the \gls{IOT} only started when there where as many connected devices as there were people on the globe, i.e.\ around 2008 \citep{evans_internet_2011}.
Today, the \gls{IOT} is the term for a system of devices that sense the environment, act upon it and communicate with each other and the world.
These connected devices are already in households all around us in the form of smart electricity meters, fridges, phones, watches, home automation, \etc.
While devices are getting a bit faster, smaller, and cheaper, they keep these properties to an extent, greatly reducing the flexibility for dynamic systems where tasks are created on the fly, executed on demand, or require parallel execution.
These problems can be mitigated by dynamically sending code to be interpreted to the microprocessor.
With interpretation, a specialized interpreter is flashed in the program memory once that receives the program code to execute at runtime.
+Interpretation always comes with an overhead, making it challenging to create them for small edge devices.
+However, the hardware requirements can be reduced by embedding domain-specific data into the programming language to be interpreted, so called \glspl{DSL}.
-%weiser_computer_1991
-\section{\texorpdfstring{\Glsxtrlongpl{DSL}}{Domain-specific languages}}
+\section{\texorpdfstring{\Glsxtrlongpl{DSL}}{Domain-specific languages}}\label{sec:back_dsl}
% General
-Programming languages can be divided up into two categories: \glspl{DSL}\footnote{Historically this has been called DSEL as well.} and \glspl{GPL}~\citep{fowler_domain_2010}.
+Programming languages can be divided up into two categories: \glspl{DSL}\footnote{Historically this has been called DSEL as well.} 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 an \gls{DSL} is easy but this may come at the cost of the \gls{DSL} being less expressive to an extent that it may not even be Turing complete.
\Glspl{DSL} come in two main flavours: standalone and embedded\footnote{Also called external and internal respectively.} of which \glspl{EDSL} can again be classified into heterogeneous and homogeneous languages (see \cref{fig:hyponymy_of_dsls} for this hyponymy).
\begin{figure}[ht]
\centering
\includestandalone{hyponymy_of_dsls}
- \caption{Hyponymy of \glspl{DSL} (adapted from \citet[pg.\ 2]{mernik_extensible_2013})}%
+ \caption{Hyponymy of \glspl{DSL} (adapted from \citet[\citepage{2}]{mernik_extensible_2013})}%
\label{fig:hyponymy_of_dsls}
\end{figure}
Unfortunately it also means that they need to develop a compiler or interpreter for the language to be usable making standalone \glspl{DSL} costly to create.
Examples of standalone \glspl{DSL} are regular expressions, make, yacc, XML, SQL, \etc.
-A dichotomous approach is embedding the \gls{DSL} in a host language, i.e.\ \glspl{EDSL}~\citep{hudak_modular_1998}.
+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 and the cost of creating embedded languages is very low.
There is more linguistic reuse~\cite{krishnamurthi_linguistic_2001}.
There are however two sides to the this coin.
Furthermore, 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}.
\subsection{Heterogeneity and homogeneity}
-\Citet{tratt_domain_2008} applied a notion from metaprogramming~\citep{sheard_accomplishments_2001} to \glspl{EDSL} to define homogeneity and heterogeneity of \glspl{EDSL} as follows:
+\Citet{tratt_domain_2008} applied a notion from metaprogramming \citep{sheard_accomplishments_2001} to \glspl{EDSL} to define homogeneity and heterogeneity of \glspl{EDSL} as follows:
\begin{quote}
+ \emph{
A homogeneous system is one where all the components are specifically designed to work with each other, whereas in heterogeneous systems at least one of the components is largely, or completely, ignorant of the existence of the other parts of the system.
+}
\end{quote}
Homogeneous \glspl{EDSL} are therefore languages that are solely defined as an extension to their host language.
For example, \citep{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 both heterogeneous \glspl{EDSL} and \gls{MTASK} specifically is a compiling \gls{DSL}.
-\section{\texorpdfstring{\Glsxtrlong{TOP}}{Task-oriented programming}}
+\section{\texorpdfstring{\Glsxtrlong{TOP}}{Task-oriented programming}}\label{sec:back_top}
\Gls{TOP} is a declarative programming paradigm designed to model interactive systems \citep{plasmeijer_task-oriented_2012}.
-Instead of dividing problems into layers or tiers, as is done in \gls{IOT} architectures as well, it deals with separation of concerns in a novel way.
+Instead of dividing problems into layers or tiers, as is done in \gls{IOT} architectures, it 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}).
-This approach to software development is called \gls{TOSD}~\citep{wang_maintaining_2018}.
+This approach to software development is called \gls{TOSD} \citep{wang_maintaining_2018}.
\begin{figure}[ht]
\centering
\includestandalone{tosd}
\caption{\Gls{TOSD} approach.}
\end{subfigure}
- \caption{Separation of concerns in a traditional setting and in \gls{TOSD} (adapted from~\cite[pg.\ 20]{wang_maintaining_2018}).}%
+ \caption{Separation of concerns in a traditional setting and in \gls{TOSD} (adapted from~\cite[\citepage{20}]{wang_maintaining_2018}).}%
\label{fig:tosd}
\end{figure}
\begin{description}
\item[\Glsxtrshort{UI} (presentation layer):]
The \gls{UI} of the system is automatically generated from the representation of the type.
-% For instance, \gls{TOP} languages implemented in an \gls{FP} language often use generic programming or template metaprogramming to automatically achieve this.
-% \Gls{TOP} languages embedded in imperative programming languages may use introspection\todo{Do I want this sentence here?}.
Even though the \gls{UI} is generated from the structure of the datatypes, in practical \gls{TOP} systems it can be tweaked afterwards to suit the specific needs of the application.
\item[Tasks (business layer):]
A task is an abstract representation of a piece of work that needs to be done.
The \gls{UOD} from the business layer is explicitly and separately modelled by the relations that exist in the functions of the host language.
\end{description}
-The concept of \gls{TOP} originated from the \gls{ITASK} framework, a declarative workflow language for defining multi-user distributed web applications implemented as an \gls{EDSL} in the lazy pure \gls{FP} language \gls{CLEAN}~\citep{plasmeijer_itasks:_2007,plasmeijer_task-oriented_2012}.
+The concept of \gls{TOP} originated from the \gls{ITASK} framework, a declarative workflow language for defining multi-user distributed web applications implemented as an \gls{EDSL} in the lazy pure \gls{FP} language \gls{CLEAN} \citep{plasmeijer_itasks:_2007,plasmeijer_task-oriented_2012}.
While \gls{ITASK} conceived \gls{TOP}, it is not the only \gls{TOP} language.
Some \gls{TOP} languages arose from Master's and Bachelor's thesis projects (e.g.\ \textmu{}Task \citep{piers_task-oriented_2016} and LTasks \citep{van_gemert_task_2022}) or were created to solve a practical problem (e.g.\ Toppyt \citep{lijnse_toppyt_2022} and hTask \citep{lubbers_htask_2022}).
-Furthermore, \gls{TOPHAT} is a fully formally specified \gls{TOP} language designed to capture the essence of \gls{TOP} formally~\citep{steenvoorden_tophat_2019}.
+Furthermore, \gls{TOPHAT} is a fully formally specified \gls{TOP} language designed to capture the essence of \gls{TOP} formally \citep{steenvoorden_tophat_2019}.
created \textmu{}Task, a \gls{TOP} language for specifying non-interruptible embedded systems implemented as an \gls{EDSL} in \gls{HASKELL}.
\citet{van_gemert_task_2022} created LTasks, a \gls{TOP} language for interactive terminal applications implemented in LUA, a dynamically typed imperative language.
\citet{lijnse_toppyt_2022} created Toppyt, a \gls{TOP} language based on \gls{ITASK}, implemented in \gls{PYTHON}, but designed to be simpler and smaller.
Finally there is \gls{MTASK}, \gls{TOP} language designed for defining workflow for \gls{IOT} devices~\cite{koopman_task-based_2018}.
It is written in \gls{CLEAN} as an \gls{EDSL} fully integrated with \gls{ITASK} and allows the programmer to define all layers of an \gls{IOT} system from a single source.
-\section{Outline}
-\todo[inline]{uitbreiden}
-On Wikipedia, a rhapsody is defined as follows~\citep{wikipedia_contributors_rhapsody_2022}:
+\section{Reading guide}\label{sec:outline}
+This thesis presents a novel view on programming these \gls{IOT} systems as a purely functional rhapsody in three episodes.
+On Wikipedia, a rhapsody is defined as follows \citep{wikipedia_contributors_rhapsody_2022}:
\begin{quote}
- A \textbf{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. An air of spontaneous inspiration and a sense of improvisation make it freer in form than a set of variations.
+ \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.
+ An air of spontaneous inspiration and a sense of improvisation make it freer in form than a set of variations.}
\end{quote}
-This thesis follows the tradition and consists of three movements that are episodic yet integrated, a purely functional rhapsody.
-\Cref{prt:dsl} is about \gls{EDSL} techniques, \cref{prt:top} elaborates on \gls{TOP} for the \gls{IOT} and \cref{prt:tvt} compares traditional tiered \gls{IOT} architectures to a tierless architectures such as \gls{TOP}.
-The movements are readable independently if the reader is familiarised with the background material provided in \cref{chp:introduction}.
-The thesis wraps up with \cref{chp:conclusion} that provides a conclusion and an outlook on future work.
-\subsection*{\nameref{prt:dsl}}
-This movement is a cumulative---paper-based---movement that focusses on techniques for embedding \glspl{DSL} in \gls{FP} languages.
-After reading the first chapter, subsequent chapters in this movement are readable independently.
+\subsection*{\nameref{chp:introduction}}
+\Cref{chp:introduction} introduces the contents of the thesis, provides background material on \gls{IOT}, \glspl{DSL} and \gls{TOP} (\cref{sec:back_iot}, \cref{sec:back_dsl}, and \cref{sec:back_top} respectively) and an overview of the contributions including a more technical outline in \cref{sec:contributions}.
+
+\subsection*{\Fullref{prt:dsl}}
+
+\subsection*{\Fullref{prt:top}}
+
+\subsection*{\Fullref{prt:tvt}}
-\subsubsection*{\fullref{chp:dsl_embedding_techniques}}
-This chapter shows the basic \gls{DSL} embedding techniques and compares the properties of several embedding methods.
-This chapter is not based on a paper and written as a extra background material for the subsequent chapters in the movement.
+\subsection*{\nameref{chp:conclusion}}
+\Cref{chp:conclusion} wraps up with the coda that provides discussion and an outlook on future work.
-\subsubsection*{\fullref{chp:classy_deep_embedding}}
-This chapter is based on the paper: \bibentry{lubbers_deep_2022}\todo{change in-press when published}.
+\section{Contributions}\label{sec:contributions}
+\subsection*{\nameref{prt:dsl}}
+The \gls{MTASK} system is a heterogeneous \gls{EDSL} and during the development of it, several novel basal techniques for embedding \glspl{DSL} in \gls{FP} languages have been found.
+This first episode is a cumulative---otherwise known as paper-based---episode consisting of two papers published on novel embedding techniques.
+Both papers are readable independently.
+
+\subsubsection*{\Fullref{chp:classy_deep_embedding}}
+This chapter is based on the paper: \citeentry{lubbers_deep_2022}\todo{change in-press when published}.
While supervising \citeauthor{amazonas_cabral_de_andrade_developing_2018}'s \citeyear{amazonas_cabral_de_andrade_developing_2018} Master's thesis, focussing on an early version of \gls{MTASK}, a seed was planted for a novel deep embedding technique for \glspl{DSL} where the resulting language is extendible both in constructs and in interpretation using type classes and existential data types.
Slowly the ideas organically grew to form the technique shown in the paper.
-
-The research from this paper and writing the paper was solely performed by me.
\Cref{sec:classy_reprise} was added after publication and contains a (yet) unpublished extension of the embedding technique.
+The research from this paper and writing the paper was solely performed by me.
-\subsubsection*{\fullref{chp:first-class_datatypes}}
-This chapter is based on the paper: \bibentry{lubbers_first-class_2022}\todo{change when accepted}.
+\subsubsection*{\Fullref{chp:first-class_datatypes}}
+This chapter is based on the paper: \citeentry{lubbers_first-class_2022}\todo{change when accepted}.
It shows how to inherit data types from the host language in \glspl{EDSL} using metaprogramming.
-
+It does so by providing a proof-of-concept implementation using \gls{HASKELL}'s metaprogramming system: \gls{TH}.
+Besides showing the result, the paper also serves as a gentle introduction to using \gls{TH} and contains a thorough literature study on research that uses \gls{TH}.
The research in this paper and writing the paper was performed by me, though there were weekly meetings with Pieter Koopman and Rinus Plasmeijer in which we discussed and refined the ideas.
\subsection*{\nameref{prt:top}}
-This part is a monograph focussing on \glspl{TOP} for the \gls{IOT} and hence are the chapters best read in order.
-The monograph is compiled from the following papers and revised lecture notes.
+This is a monograph compiled from several papers and revised lecture notes on \gls{MTASK}, the \gls{TOP} system used to orchestrate the \gls{IOT}.
+It provides a gentle introduction to the \gls{MTASK} system elaborates on \gls{TOP} for the \gls{IOT}.
+\todo[inline]{outline the chapters}
\begin{itemize}
\item \citeentry{koopman_task-based_2018}
Pieter Koopman wrote it, I helped with the software and research.
\item \citeentry{lubbers_task_2018}
- This paper was an extension of my Master's thesis~\citep{lubbers_task_2017}.
+ This paper was an extension of my Master's thesis \citep{lubbers_task_2017}.
It shows how a simple imperative variant of \gls{MTASK} was integrated with \gls{ITASK}.
While the language was a lot different than later versions, the integration mechanism is still used in \gls{MTASK} today.
The research in this paper and writing the paper was performed by me, though there were weekly meetings with Pieter Koopman and Rinus Plasmeijer in which we discussed and refined the ideas.
\item \citeentry{koopman_simulation_2018}\footnotemark[\value{footnote}]\todo{change when published}
These revised lecture notes are from a course on the \gls{MTASK} simulator was provided at the 2018 \gls{CEFP}/\gls{3COWS} winter school in Ko\v{s}ice, Slovakia.
-
Pieter Koopman wrote and taught it, I helped with the software and research.
\item \citeentry{lubbers_writing_2019}\footnotemark[\value{footnote}]\todo{change when published}
These revised lecture notes are from a course on programming in \gls{MTASK} provided at the 2019 \gls{CEFP}/\gls{3COWS} summer school in Budapest, Hungary.
-
Pieter Koopman prepared and taught half of the lecture and supervised the practical session.
I taught the other half of the lecture, wrote the lecture notes, made the assignments and supervised the practical session.
\item \citeentry{lubbers_interpreting_2019}
This paper shows an implementation for \gls{MTASK} for microcontrollers in the form of a compilation scheme and informal semantics description.
-
The research in this paper and writing the paper was performed by me, though there were weekly meetings with Pieter Koopman and Rinus Plasmeijer.
\item \citeentry{crooijmans_reducing_2022}\todo{change when published}
This paper shows how to create a scheduler so that devices running \gls{MTASK} tasks can go to sleep more automatically.
- Furthermore, it shows how to integrate hardware interrupts into \gls{MTASK}.
The research was carried out by \citet{crooijmans_reducing_2021} during his Master's thesis.
I did the daily supervision and helped with the research, Pieter Koopman was the formal supervisor and wrote most of the paper.
\item \emph{Green Computing for the Internet of Things}\footnote{
This work acknowledges the support of the Erasmus+ project ``SusTrainable---Promoting Sustainability as a Fundamental Driver in Software Development Training and Education'', no. 2020--1--PT01--KA203--078646}\todo{change when published}
These revised lecture notes are from a course on sustainable programming using \gls{MTASK} provided at the 2022 SusTrainable summer school in Rijeka, Croatia.
-
Pieter prepared and taught a quarter of the lecture and supervised the practical session.
I prepared and taught the other three quarters of the lecture, made the assignments and supervised the practical session\todo{writing contribution}.
\end{itemize}
\subsection*{\nameref{prt:tvt}}
+\Cref{prt:tvt} is based on a journal paper that quantitatively and qualitatively compares traditional \gls{IOT} architectures with \gls{IOT} systems using \gls{TOP} and contains a single chapter.
This chapter is based on the journal paper: \citeentry{lubbers_could_2022}\todo{change when published}\footnote{This work is an extension of the conference article: \citeentry{lubbers_tiered_2020}\footnotemark{}}.
\footnotetext{This paper was partly funded by the Radboud-Glasgow Collaboration Fund.}
-It compares programming traditional tiered architectures to tierless architectures by showing a qualitative and a quantitative four-way comparison of a smart campus application.
-
+It compares programming traditional tiered architectures to tierless architectures by showing a qualitative and a quantitative four-way comparison of a smart-campus application.
Writing the paper was performed by all authors.
I created the server application, the \gls{CLEAN}/\gls{ITASK}/\gls{MTASK} implementation (\glsxtrshort{CWS}) and the \gls{CLEAN}/\gls{ITASK} implementation (\glsxtrshort{CRS})
-Adrian Ramsingh created the \gls{MICROPYTHON} implementation (\glsxtrshort{PWS}), the original \gls{PYTHON} implementation (\glsxtrshort{PRS}) and the server application were created by Jeremy Singer, Dejice Jacob and Kristian Hentschel~\citep{hentschel_supersensors:_2016}.
+Adrian Ramsingh created the \gls{MICROPYTHON} implementation (\glsxtrshort{PWS}), the original \gls{PYTHON} implementation (\glsxtrshort{PRS}) and the server application were created by \citet{hentschel_supersensors:_2016}.
\input{subfilepostamble}
\end{document}
\pagenumbering{arabic}
}{}
-\chapter{Introduction to \texorpdfstring{\gls{IOT}}{IoT} programming}%
+\chapter{Introduction to \texorpdfstring{\glsxtrshort{IOT}}{IoT} device programming}%
\label{chp:top4iot}
\todo{betere chapter naam}
\begin{chapterabstract}
This chapter introduces \gls{MTASK} and puts it into perspective compared to traditional microprocessor programming.
\end{chapterabstract}
+The edge layer of \gls{IOT} system mostly consists of microprocessors that require a different method of programming.
+Usually, programming microprocessors requires an elaborate multi-step toolchain of compilation, linkage, binary image creation, and burning this image onto the flash memory of the microprocessor in order to compile and run a program.
+The programs are usually cyclic executives instead of tasks running in an operating system, i.e.\ there is only a single task that continuously runs on the bare metal.
+Each type of microprocessors comes with vendor-provided drivers, compilers and \glspl{RTS} but there are many platform that abstract away from this such as \gls{MBED} and \gls{ARDUINO} of which \gls{ARDUINO} is specifically designed for education and prototyping and hence used here.
+The popular \gls{ARDUINO} \gls{C}\slash\gls{CPP} dialect and accompanying libraries provide an abstraction layer for common microprocessor behaviour allowing the programmer to program multiple types of microprocessors 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.
+It provides an \gls{IDE} and toolchain automation to perform all steps of the toolchain with a single command.
+
+\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.
-On microprocessors, there often is no screen for displaying text.
-Nevertheless, almost always there is a monochrome $1\times1$ pixel screen, namely an---often builtin---\gls{LED}.
+On microprocessors, there usually is no screen for displaying text.
+Nevertheless, almost always there is a built-in monochrome $1\times1$ pixel screen, namely an \gls{LED}.
The \emph{Hello World!} equivalent on microprocessors blinks this \gls{LED}.
-\Cref{lst:arduinoBlink} shows how the logic of a blink program might look when using \gls{ARDUINO}'s \gls{CPP} dialect.
+\Cref{lst:arduinoBlink} shows how the logic of a blink program might look when using \gls{ARDUINO}'s \gls{C}\slash\gls{CPP} dialect.
Every \gls{ARDUINO} program contains 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.
After setting the \gls{GPIO} pin to the correct mode, blink's \arduinoinline{loop} function alternates the state of the pin representing the \gls{LED} between \arduinoinline{HIGH} and \arduinoinline{LOW}, turning the \gls{LED} off and on respectively.
-In between it waits for 500 milliseconds so that the blinking is actually visible for the human eye.
-Compiling this results in a binary firmware that needs to be flashed onto the program memory.
+In between it waits for \qty{500}{\ms} so that the blinking is actually visible for the human eye.
Translating the traditional blink program to \gls{MTASK} can almost 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 can be used, this task executes the argument task and, when stable, reinstates it.
+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.
delay(500);
digitalWrite(D2, LOW);
delay(500);
-}\end{lstArduino}
+}
+ \end{lstArduino}
\end{subfigure}%
\begin{subfigure}[b]{.5\linewidth}
\begin{lstClean}[caption={Blink program.},label={lst:blinkImp}]
>>|. writeD d2 false
>>|. delay (lit 500)
)
-}\end{lstClean}
+}
+ \end{lstClean}
\end{subfigure}
\end{figure}
\section{Threaded blinking}
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 $500,300$ and $800$ milliseconds.
+For example, blink three \glspl{LED} connected to \gls{GPIO} pins $1,2$ and $3$ at intervals of \qtylist{500;300;800}{\ms}.
Intuitively you want to lift the blinking behaviour to a function and call this function three times with different parameters as done in \cref{lst:blinkthreadno}
\begin{lstArduino}[caption={Naive approach to multiple blinking patterns.},label={lst:blinkthreadno}]
Unfortunately, this does not work because the \arduinoinline{delay} function blocks all further execution.
The resulting program will blink the \glspl{LED} after each other instead of at the same time.
-To overcome this, it is necessary to slice up the blinking behaviour in very small fragments so it can be manually interleaved~\citep{feijs_multi-tasking_2013}.
+To overcome this, it is necessary to slice up the blinking behaviour in very small fragments so it can be manually interleaved \citep{feijs_multi-tasking_2013}.
Listing~\ref{lst:blinkthread} shows how three different blinking patterns might be achieved in \gls{ARDUINO} using the slicing method.
If we want the blink function to be a separate parametrizable function we need to explicitly provide all references to the required state.
Furthermore, the \arduinoinline{delay} function can not be used and polling \arduinoinline{millis} is required.
}\end{lstClean}
% VimTeX: SynIgnore off
-\chapter{The \texorpdfstring{\gls{MTASK}}{mTask} \texorpdfstring{\gls{DSL}}{DSL}}%
+\section{\texorpdfstring{\Gls{MTASK}}{MTask} history}
+\subsection{Generating \texorpdfstring{\gls{C}/\gls{CPP}}{C/C++} code}
+A first throw at a class-based shallowly \gls{EDSL} for microprocessors was made by \citet{plasmeijer_shallow_2016}.
+The language was called \gls{ARDSL} and offered a type safe interface to \gls{ARDUINO} \gls{CPP} dialect.
+A \gls{CPP} code generation backend was available together with an \gls{ITASK} simulation backend.
+There was no support for tasks or even functions.
+Some time later in the 2015 \gls{CEFP} summer school, an extended version was created that allowed the creation of imperative tasks, \glspl{SDS} and the usage of functions \citep{koopman_type-safe_2019}.
+The name then changed from \gls{ARDSL} to \gls{MTASK}.
+
+\subsection{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}
+\Citet{lubbers_task_2017} extended this in his Master's Thesis by adding integration with \gls{ITASK} and a bytecode compiler to the language.
+\Gls{SDS} in \gls{MTASK} could be accessed on the \gls{ITASK} server.
+In this way, entire \gls{IOT} systems could be programmed from a single source.
+However, this version used a simplified version of \gls{MTASK} without functions.
+This was later improved upon by creating a simplified interface where \glspl{SDS} from \gls{ITASK} could be used in \gls{MTASK} and the other way around \citep{lubbers_task_2018}.
+It was shown by \citet{amazonas_cabral_de_andrade_developing_2018} that it was possible to build real-life \gls{IOT} systems with this integration.
+Moreover, a course on the \gls{MTASK} simulator was provided at the 2018 \gls{CEFP}/\gls{3COWS} winter school in Ko\v{s}ice, Slovakia \citep{koopman_simulation_2018}.
+
+\section{Transition to \texorpdfstring{\gls{TOP}}{TOP}}
+The \gls{MTASK} language as it is now was introduced in 2018 \citep{koopman_task-based_2018}.
+This paper updated the language to support functions, tasks and \glspl{SDS} but still compiled to \gls{CPP} \gls{ARDUINO} code.
+Later the bytecode compiler and \gls{ITASK} integration was added to the language \citep{lubbers_interpreting_2019}.
+Moreover, it was shown that it is very intuitive to write microprocessor applications in a \gls{TOP} language \citep{lubbers_multitasking_2019}.
+One reason for this is that a lot of design patterns that are difficult using standard means are for free in \gls{TOP} (e.g.\ multithreading).
+In 2019, the \gls{CEFP} summer school in Budapest, Hungary hosted a course on developing \gls{IOT} applications with \gls{MTASK} as well \citep{lubbers_writing_2019}.
+
+\subsection{\texorpdfstring{\Glsxtrshort{TOP}}{TOP}}
+In 2022, the SusTrainable summer school in Rijeka, Croatia hosted a course on developing greener \gls{IOT} applications using \gls{MTASK} as well (the lecture notes are to be written).
+Several students worked on extending \gls{MTASK} with many useful features:
+\Citet{veen_van_der_mutable_2020} did preliminary work on a green computer analysis, built a simulator and explored the possibilities for adding bounded datatypes; \citet{boer_de_secure_2020} investigated the possibilities for secure communication channels; and \citet{crooijmans_reducing_2021} added abstractions for low-power operation to \gls{MTASK} such as hardware interrupts and power efficient scheduling (resulting in a paper as well \citet{crooijmans_reducing_2022}).
+\Citet{antonova_mtask_2022} defined a preliminary formal semantics for a subset of \gls{MTASK}.
+Moreover, plans for student projects and improvements include exploring integrating \gls{TINYML} into \gls{MTASK}; and adding intermittent computing support to \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}.
+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.
+
+\chapter{The \texorpdfstring{\gls{MTASK}}{mTask} \texorpdfstring{\glsxtrshort{DSL}}{DSL}}%
\label{chp:mtask_dsl}
\begin{chapterabstract}
This chapter serves as a complete guide to the \gls{MTASK} language, from an \gls{MTASK} programmer's perspective.
\end{chapterabstract}
-The \gls{MTASK} system is a \gls{TOP} programming environment for programming microprocessors.
-It is implemented as an\gls{EDSL} in \gls{CLEAN} using class-based---or tagless-final---embedding (See \cref{ssec:tagless}).
-Due to the nature of the embedding technique, it is possible to have multiple interpretations of---or views on---programs written in the \gls{MTASK} language.
+The \gls{MTASK} system is a complete \gls{TOP} programming environment for programming microprocessors.
+It is implemented as an \gls{EDSL} in \gls{CLEAN} using class-based---or tagless-final---embedding (see \cref{sec:tagless-final_embedding}).
+
+Due to the nature of the embedding technique, it is possible to have multiple views on-programs written in the \gls{MTASK} language.
The following interpretations are available for \gls{MTASK}.
-\begin{itemize}
- \item Pretty printer
+\begin{description}
+ \item[Pretty printer]
This interpretation converts the expression to a string representation.
- \item Simulator
+ \item[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.
- \item Compiler
+ \item[Byte code compiler]
- The compiler compiles the \gls{MTASK} program at runtime to a specialised bytecode.
+ The compiler compiles the \gls{MTASK} program at runtime to a specialised byte code.
Using a handful of integration functions and tasks, \gls{MTASK} tasks can be executed on microprocessors 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{itemize}
+\end{description}
When using the compiler interpretation in conjunction with the \gls{ITASK} integration, \gls{MTASK} is a heterogeneous \gls{DSL}.
-I.e.\ some components---e.g.\ the \gls{RTS} on the microprocessor---is largely unaware of the other components in the system.
-Furthermore, it is executed on a completely different architecture.
-The \gls{MTASK} language consists of a host language---a simply-typed $\lambda$-calculua with support for some basic types, function definition and data types (see \cref{sec:expressions})---enriched with a task language (see \cref{sec:top}).
+I.e.\ some components---e.g.\ the \gls{RTS} on the microprocessor---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}
To leverage the type checker of the host language, types in the \gls{MTASK} language are expressed as types in the host language, to make the language type safe.
\label{tbl:mtask-c-datatypes}
\end{table}
-The \gls{MTASK} language consists of a core collection of type classes bundled in the type class \cleaninline{class mtask}.
+\Cref{lst:constraints} contains the definitions for the auxiliary types and type constraints (such as \cleaninline{type} an \cleaninline{basicType}) that are used to construct \gls{MTASK} expressions.
+The \gls{MTASK} language interface consists of a core collection of type classes bundled in the type class \cleaninline{class mtask}.
Every interpretation implements the type classes in the \cleaninline{mtask} class
-There are also \gls{MTASK} extensions that not every interpretation implements such as peripherals and integration with \gls{ITASK}.
-
-\Cref{lst:constraints} contains the definitions for the type constraints and shows some example type signatures for typical \gls{MTASK} expressions and tasks.
-\todo{uitleggen}
-
+There are also \gls{MTASK} extensions that not every interpretation implements such as peripherals and \gls{ITASK} integration.
\begin{lstClean}[caption={Classes and class collections for the \gls{MTASK} language.},label={lst:constraints}]
-:: Main a = { main :: a }
-:: In a b = (In) infix 0 a b
-
class type t | iTask, ... ,fromByteCode, toByteCode t
class basicType t | type t where ...
class mtask v | expr, ..., int, real, long v
-someExpr :: v Int | mtask v
-someExpr = ...
+\end{lstClean}
+
+Sensors, \glspl{SDS}, functions, \etc{} may only be defined at the top level.
+The \cleaninline{Main} type is used that is used to distinguish the top level from the main expression.
+Some top level definitions, such as functions, are defined using \gls{HOAS}.
+To make their syntax friendlier, the \cleaninline{In} type---an infix tuple---is used to combine these top level definitions as can be seen in \cleaninline{someTask} (\cref{lst:mtask_types}).
-someTask :: MTask v Int | mtask v
+\begin{lstClean}[caption={Example task and auxiliary types in the \gls{MTASK} language.},label={lst:mtask_types}]
+:: Main a = { main :: a }
+:: In a b = (In) infix 0 a b
+
+someTask :: MTask v Int | mtask v & liftsds v & sensor1 v & ...
someTask =
sensor1 config1 \sns1->
sensor2 config2 \sns2->
- fun \fun1= ( ... )
+ sds \s1=initial
+ In liftsds \s2=someiTaskSDS
+ In fun \fun1= ( ... )
In fun \fun2= ( ... )
- In {main=mainexpr}
+ In { main = mainexpr }
\end{lstClean}
\section{Expressions}\label{sec:expressions}
\Cref{lst:expressions} shows the \cleaninline{expr} class containing the functionality to lift values from the host language to the \gls{MTASK} language (\cleaninline{lit}); perform number and boolean arithmetics; do comparisons; and conditional execution.
-For every common arithmetic operator in the host language, an \gls{MTASK} variant is present, suffixed by a period to not clash with \gls{CLEAN}'s builtin operators.
+For every common boolean and arithmetic operator in the host language, an \gls{MTASK} variant is present, suffixed by a period to not clash with \gls{CLEAN}'s builtin operators.
\begin{lstClean}[caption={The \gls{MTASK} class for expressions},label={lst:expressions}]
class expr v where
If :: (v Bool) (v t) (v t) -> v t | type t
\end{lstClean}
-Conversion to-and-fro data types is available through the overloaded functions \cleaninline{int}, \cleaninline{long} and \cleaninline{real}.
+Conversion to-and-fro data types is available through the overloaded functions \cleaninline{int}, \cleaninline{long} and \cleaninline{real} that will convert the argument to the respective type similar to casting in \gls{C}.
\begin{lstClean}[caption={Type conversion functions in \gls{MTASK}.}]
class int v a :: (v a) -> v Int
class long v a :: (v a) -> v Long
\end{lstClean}
-Finally, values from the host language must be explicitly lifted to the \gls{MTASK} language using the \cleaninline{lit} function.
+Values from the host language must be explicitly lifted to the \gls{MTASK} language using the \cleaninline{lit} function.
For convenience, there are many lower-cased macro definitions for often used constants such as \cleaninline{true :== lit True}, \cleaninline{false :== lit False}, \etc.
\Cref{lst:example_exprs} shows some examples of these expressions.
+Since they are only expressions, there is no need for a \cleaninline{Main}.
\cleaninline{e0} defines the literal $42$, \cleaninline{e1} calculates the literal $42.0$ using real numbers.
\cleaninline{e2} compares \cleaninline{e0} and \cleaninline{e1} as integers and if they are equal it returns the \cleaninline{e2}$/2$ and \cleaninline{e0} otherwise.
-\cleaninline{approxEqual} performs an approximate equality---albeit not taking into account all floating point pecularities---and demonstrates that \gls{CLEAN} can be used as a macro language, i.e.\ maximise linguistic reuse~\cite{krishnamurthi_linguistic_2001}.
-\todo{uitzoeken waar dit handig is}
-When calling \cleaninline{approxEqual} in an \gls{MTASK} function, the resulting code is inlined.
\begin{lstClean}[label={lst:example_exprs},caption={Example \gls{MTASK} expressions.}]
e0 :: v Int | expr v
e2 :: v Int | expr v
e2 = if' (e0 ==. int e1)
(int e1 /. lit 2) e0
+\end{lstClean}
+
+\Gls{MTASK} is shallowly embedded in \gls{CLEAN} and the terms are constructed at runtime.
+This means that \gls{MTASK} programs can also be tailor-made at runtime or constructed using \gls{CLEAN} functions maximising the linguistic reuse \citep{krishnamurthi_linguistic_2001}
+\cleaninline{approxEqual} in \cref{lst:example_macro} performs an approximate equality---albeit not taking into account all floating point pecularities---.
+When calling \cleaninline{approxEqual} in an \gls{MTASK} function, the resulting code is inlined.
+\begin{lstClean}[label={lst:example_macro},caption={Example linguistic reuse in the \gls{MTASK} language.}]
approxEqual :: (v Real) (v Real) (v Real) -> v Real | expr v
-approxEqual x y eps = if' (x == y) true
- ( if' (x > y)
+approxEqual x y eps = if' (x ==. y) true
+ ( if' (x >. y)
(y -. x < eps)
(x -. y < eps)
)
\end{lstClean}
-\subsection{Data Types}
+\subsection{Data types}
Most of \gls{CLEAN}'s basic types have been mapped on \gls{MTASK} types.
However, it can be useful to have access to compound types as well.
All types in \gls{MTASK} must have a fixed size representation on the stack so sum types are not (yet) supported.
While it is possible to lift types using the \cleaninline{lit} function, you cannot do anything with the types besides passing them around but they are being produced by some parallel task combinators (see \cref{sssec:combinators_parallel}).
-To be able to use types as first class citizens, constructors and field selectors are required.
+To be able to use types as first class citizens, constructors and field selectors are required (see \cref{chp:first-class_datatypes}).
\Cref{lst:tuple_exprs} shows the scaffolding for supporting tuples in \gls{MTASK}.
Besides the constructors and field selectors, there is also a helper function available that transforms a function from a tuple of \gls{MTASK} expressions to an \gls{MTASK} expression of a tuple.
+Examples for using tuple can be found in \cref{sec:mtask_functions}.
\begin{lstClean}[label={lst:tuple_exprs},caption={Tuple constructor and field selectors in \gls{MTASK}.}]
class tupl v where
tupopen f :== \v->f (first v, second v)
\end{lstClean}
-\subsection{Functions}
-Adding functions to the language is achieved by one multi-parameter class to the \gls{DSL}.
-By using \gls{HOAS}, both the function definition and the calls to the function can be controlled by the \gls{DSL}~\citep{pfenning_higher-order_1988,chlipala_parametric_2008}.
-As \gls{MTASK} only supports first-order functions and does not allow partial function application.
-Using a type class of this form, this restriction can be enforced on the type level.
-Instead of providing one instance for all functions, a single instance per function arity is defined.
+\subsection{Functions}\label{sec:mtask_functions}
+Adding functions to the language is achieved by type class to the \gls{DSL}.
+By using \gls{HOAS}, both the function definition and the calls to the function can be controlled by the \gls{DSL} \citep{pfenning_higher-order_1988,chlipala_parametric_2008}.
+The \gls{MTASK} only allows first-order functions and does not allow partial function application.
+This is restricted by using a multi-parameter type class where the first parameter represents the arguments and the second parameter the view.
+By providing a single instance per function arity instead of providing one instance for all functions and using tuples for the arguments this constraint can be enforced.
Also, \gls{MTASK} only supports top-level functions which is enforced by the \cleaninline{Main} box.
-The definition of the type class and the instances for an example interpretation are as follows:
-\todo{uitbreiden}
+The definition of the type class and the instances for an example interpretation (\cleaninline{:: Inter}) are as follows:
\begin{lstClean}[caption={Functions in \gls{MTASK}.}]
class fun a v :: ((a -> v s) -> In (a -> v s) (Main (MTask v u)))
instance fun () Inter where ...
instance fun (Inter a) Inter | type a where ...
-instance fun (Inter a, Inter b) Inter | type a where ...
-instance fun (Inter a, Inter b, Inter c) Inter | type a where ...
+instance fun (Inter a, Inter b) Inter | type a, type b where ...
+instance fun (Inter a, Inter b, Inter c) Inter | type a, ... where ...
...
\end{lstClean}
\end{lstClean}
% VimTeX: SynIgnore off
-\section{Tasks}\label{sec:top}
+\section{Tasks and task combinators}\label{sec:top}
\Gls{MTASK}'s task language can be divided into three categories, namely
\begin{enumerate*}
\item Basic tasks, in most \gls{TOP} systems, the basic tasks are called editors, modelling the interactivity with the user.
\subsubsection{Peripherals}\label{sssec:peripherals}
For every sensor or actuator, basic tasks are available that allow interaction with the specific peripheral.
The type classes for these tasks are not included in the \cleaninline{mtask} class collection as not all devices nor all language interpretations have such peripherals connected.
-\todo{Historically, peripheral support has been added \emph{by need}.}
+%\todo{Historically, peripheral support has been added \emph{by need}.}
\Cref{lst:dht,lst:gpio} show the type classes for \glspl{DHT} sensors and \gls{GPIO} access.
Other peripherals have similar interfaces, they are available in the \cref{sec:aux_peripherals}.
\chapter{Green computing with \texorpdfstring{\gls{MTASK}}{mTask}}%
\label{chp:green_computing_mtask}
+\section{Green \texorpdfstring{\glsxtrshort{IOT}}{IoT} computing}
+
+\section{Task scheduling}
+\subsection{Language}
+\subsection{Device}
+
+\section{Interrupts}
+
\chapter{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}%
\label{chp:integration_with_itask}
The \gls{MTASK} language is a multi-view \gls{DSL}, i.e.\ there are multiple interpretations possible for a single \gls{MTASK} term.
\section{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}
IFL18 paper stukken
-\chapter{\texorpdfstring{\gls{MTASK}}{mTask} history}
-\section{Generating \texorpdfstring{\gls{C}/\gls{CPP}}{C/C++} code}
-A first throw at a class-based shallowly \gls{EDSL} for microprocessors was made by \citet{plasmeijer_shallow_2016}.
-The language was called \gls{ARDSL} and offered a type safe interface to \gls{ARDUINO} \gls{CPP} dialect.
-A \gls{CPP} code generation backend was available together with an \gls{ITASK} simulation backend.
-There was no support for tasks or even functions.
-Some time later in the 2015 \gls{CEFP} summer school, an extended version was created that allowed the creation of imperative tasks, \glspl{SDS} and the usage of functions~\citep{koopman_type-safe_2019}.
-The name then changed from \gls{ARDSL} to \gls{MTASK}.
-
-\section{Integration with \texorpdfstring{\gls{ITASK}}{iTask}}
-Mart Lubbers extended this in his Master's Thesis by adding integration with \gls{ITASK} and a bytecode compiler to the language~\citep{lubbers_task_2017}.
-\Gls{SDS} in \gls{MTASK} could be accessed on the \gls{ITASK} server.
-In this way, entire \gls{IOT} systems could be programmed from a single source.
-However, this version used a simplified version of \gls{MTASK} without functions.
-This was later improved upon by creating a simplified interface where \glspl{SDS} from \gls{ITASK} could be used in \gls{MTASK} and the other way around~\citep{lubbers_task_2018}.
-It was shown by Matheus Amazonas Cabral de Andrade that it was possible to build real-life \gls{IOT} systems with this integration~\citep{amazonas_cabral_de_andrade_developing_2018}.
-Moreover, a course on the \gls{MTASK} simulator was provided at the 2018 \gls{CEFP}/\gls{3COWS} winter school in Ko\v{s}ice, Slovakia~\citep{koopman_simulation_2018}.
-
-\section{Transition to \texorpdfstring{\gls{TOP}}{TOP}}
-The \gls{MTASK} language as it is now was introduced in 2018~\citep{koopman_task-based_2018}.
-This paper updated the language to support functions, tasks and \glspl{SDS} but still compiled to \gls{CPP} \gls{ARDUINO} code.
-Later the bytecode compiler and \gls{ITASK} integration was added to the language~\citep{lubbers_interpreting_2019}.
-Moreover, it was shown that it is very intuitive to write microprocessor applications in a \gls{TOP} language~\citep{lubbers_multitasking_2019}.
-One reason for this is that a lot of design patterns that are difficult using standard means are for free in \gls{TOP} (e.g.\ multithreading).
-In 2019, the \gls{CEFP} summer school in Budapest, Hungary hosted a course on developing \gls{IOT} applications with \gls{MTASK} as well~\citep{lubbers_writing_2019}.
-
-\section{\texorpdfstring{\gls{TOP}}{TOP}}
-In 2022, the SusTrainable summer school in Rijeka, Croatia hosted a course on developing greener \gls{IOT} applications using \gls{MTASK} as well (the lecture notes are to be written).
-Several students worked on extending \gls{MTASK} with many useful features:
-Erin van der Veen did preliminary work on a green computer analysis, built a simulator and explored the possibilities for adding bounded datatypes~\citep{veen_van_der_mutable_2020}; Michel de Boer investigated the possibilities for secure communication channels~\citep{boer_de_secure_2020}; and Sjoerd Crooijmans added abstractions for low-power operation to \gls{MTASK} such as hardware interrupts and power efficient scheduling~\citep{crooijmans_reducing_2021}.
-Elina Antonova defined a preliminary formal semantics for a subset of \gls{MTASK}~\citep{antonova_MTASK_2022}.
-Moreover, plans for student projects and improvements include exploring integrating \gls{TINYML} into \gls{MTASK}; and adding intermittent computing support to \gls{MTASK}.
-
-In 2023, the SusTrainable summer school in Coimbra, Portugal will host a course on \gls{MTASK} as well.
-
-\section{\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}.
-The collaboration is still ongoing and a journal article is under review comparing four approaches for the edge layer: \gls{PYTHON}, \gls{MICROPYTHON}, \gls{ITASK} and \gls{MTASK}.
-Furthermore, 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
-
\input{subfilepostamble}
\end{document}
\section{Introduction}%
\label{sec_t4t:Intro}
-Conventional \gls{IOT} software stacks are notoriously complex and pose very significant software development, reliability, and maintenance challenges. \Gls{IOT} software architectures typically comprise multiple components organised in four or more tiers or layers~\citep{sethi2017internet,Ravulavaru18,Alphonsa20}. This is due to the highly distributed nature of typical \gls{IOT} applications that must read sensor data from end points (the \emph{perception} layer), aggregate and select the data and communicate over a network (the \emph{network} layer), store the data in a database and analyse it (the \emph{application} layer) and display views of the data, commonly on web pages (the \emph{presentation} layer).
+Conventional \gls{IOT} software stacks are notoriously complex and pose very significant software development, reliability, and maintenance challenges. \Gls{IOT} software architectures typically comprise multiple components organised in four or more tiers or layers \citep{sethi2017internet,Ravulavaru18,Alphonsa20}. This is due to the highly distributed nature of typical \gls{IOT} applications that must read sensor data from end points (the \emph{perception} layer), aggregate and select the data and communicate over a network (the \emph{network} layer), store the data in a database and analyse it (the \emph{application} layer) and display views of the data, commonly on web pages (the \emph{presentation} layer).
Conventional \gls{IOT} software architectures require the development of separate programs in various programming languages for each of the components/tiers in the stack. This is modular, but a significant burden for developers, and some key challenges are as follows.
\begin{enumerate*}
\item The developer must deal with the potentially diverse failure modes of each component, and of component interoperations.
\end{enumerate*}
-A radical alternative development paradigm uses a single \emph{tierless} language that synthesizes all components/tiers in the software stack. There are established \emph{tierless} languages for web stacks, e.g.\ Links~\citep{cooper2006links} or Hop~\citep{serrano2006hop}.
+A radical alternative development paradigm uses a single \emph{tierless} language that synthesizes all components/tiers in the software stack. There are established \emph{tierless} languages for web stacks, e.g.\ Links \citep{cooper2006links} or Hop \citep{serrano2006hop}.
In a tierless language the developer writes the application as a single program. The code for different tiers is simultaneously checked by the compiler, and compiled to the required component languages. For example, Links compiles to HTML and JavaScript for the web client and to SQL on the server to interact with the database system. Tierless languages for \gls{IOT} stacks are more recent and less common, examples include
-Potato~\citep{troyer_building_2018} and \gls{CLEAN} with \gls{ITASK}\slash\gls{MTASK}~\citep{lubbers_interpreting_2019}.
+Potato \citep{troyer_building_2018} and \gls{CLEAN} with \gls{ITASK}\slash\gls{MTASK} \citep{lubbers_interpreting_2019}.
\Gls{IOT} sensor nodes may be microprocessors with very limited compute resources, or supersensors: resource-rich single board computers like a Raspberry Pi. A tierless language may target either class of sensor node, and microcontrollers are the more demanding target due to the limited resources, e.g.\ small memory, executing on bare metal \etc.
Potentially a tierless language both reduces the development effort and improves correctness as correct interoperation and communication is automatically generated by the compiler. A tierless language may, however, introduce other problems. How expressive is the language? That is, can it readily express the required functionality? How maintainable is the software? Is the generated code efficient in terms of time, space, and power?
-This paper reports a systematic comparative evaluation of two tierless language technologies for \gls{IOT} stacks: one targeting resource-constrained microprocessors, and the other resource-rich supersensors. The basis of the comparison is four implementations of a typical smart campus \gls{IOT} stack~\citep{hentschel_supersensors:_2016}. Two implementations are conventional tiered \gls{PYTHON}-based stacks: \gls{PRS} and \gls{PWS}. The other two implementations are tierless: \gls{CRS} and \gls{CWS}. Our work makes the following research contributions, and the key results are summarised, discussed, and quantified in \cref{sec_t4t:Conclusion}.
+This paper reports a systematic comparative evaluation of two tierless language technologies for \gls{IOT} stacks: one targeting resource-constrained microprocessors, and the other resource-rich supersensors. The basis of the comparison is four implementations of a typical smart campus \gls{IOT} stack \citep{hentschel_supersensors:_2016}. Two implementations are conventional tiered \gls{PYTHON}-based stacks: \gls{PRS} and \gls{PWS}. The other two implementations are tierless: \gls{CRS} and \gls{CWS}. Our work makes the following research contributions, and the key results are summarised, discussed, and quantified in \cref{sec_t4t:Conclusion}.
\begin{description}
\item[C1] We show that \emph{tierless languages have the potential to significantly reduce the development effort for \gls{IOT} systems}.
- We systematically compare code size (\gls{SLOC}) of the four smart campus implementations as a measure of development effort and maintainability~\citep{alpernaswonderful,rosenberg1997some}.
+ We systematically compare code size (\gls{SLOC}) of the four smart campus implementations as a measure of development effort and maintainability \citep{alpernaswonderful,rosenberg1997some}.
The tierless implementations require 70\% less code than the tiered implementations. We analyse the codebases to attribute the code reduction to three factors.
\begin{enumerate*}
\item Tierless languages benefit from reduced interoperation, requiring far fewer languages, paradigms and source code files e.g.\ \gls{CWS} uses two languages, one paradigm and three source code files where \gls{PWS} uses seven languages, two paradigms and 35 source code files
We show that the bare metal execution environment enforces some restrictions on \gls{MTASK} although they remain high level. Moreover, the environment conveys some advantages, e.g.\ better control over timing (\cref{sec_t4t:ComparingTierless}).
\end{description}
-The current work extends~\citep{lubbers_tiered_2020} as follows. Contributions C3 and C4 are entirely new, and C1 is enhanced by being based on the analysis of four rather than two languages and implementations.
+The current work extends \citep{lubbers_tiered_2020} as follows. Contributions C3 and C4 are entirely new, and C1 is enhanced by being based on the analysis of four rather than two languages and implementations.
\section{Background and related work}%
\label{sec_t4t:Background}
access to sensor data through a RESTful \gls{API}.
This allows campus stakeholders to add functionality at a business layer above the layers that we consider here. To date,
simple apps have been developed including room temperature
-monitors and campus utilization maps~\citep{hentschel_supersensors:_2016}.
+monitors and campus utilization maps \citep{hentschel_supersensors:_2016}.
A longitudinal study of sensor accuracy has also been
-conducted~\citep{harth_predictive_2018}.
+conducted \citep{harth_predictive_2018}.
-\subsection{\texorpdfstring{\Gls{IOT}}{IoT} applications}%
+\subsection{\texorpdfstring{\Glsxtrlong{IOT}}{IoT} applications}%
\label{sec_t4t:Stacks}
Web applications are necessarily complex distributed systems, with client browsers interacting with a remote webserver and data store. Typical \gls{IOT} applications
are even more complex as they combine a web application with a second distributed system of sensor and actuator nodes that collect and aggregate data, operate on it, and communicate with the server.
Both web and \gls{IOT} applications are commonly structured into tiers, e.g.\ the classical four-tier Linux, Apache, MySQL and PHP (LAMP) stack.
-\Gls{IOT} stacks typically have more tiers than webapps, with the number depending on the complexity of the application~\citep{sethi2017internet}. While other tiers, like the business layer~\citep{muccini2018iot} may be added above them, the focus of our study is on programming the lower four tiers of the \gls{PRS}, \gls{CRS}, \gls{PWS} and \gls{CWS} stacks, as illustrated in \cref{fig_t4t:iot_arch}.
+\Gls{IOT} stacks typically have more tiers than webapps, with the number depending on the complexity of the application \citep{sethi2017internet}. While other tiers, like the business layer \citep{muccini2018iot} may be added above them, the focus of our study is on programming the lower four tiers of the \gls{PRS}, \gls{CRS}, \gls{PWS} and \gls{CWS} stacks, as illustrated in \cref{fig_t4t:iot_arch}.
-\begin{description}%[style=nextline]
+\begin{description}[style=sameline]
\item [Perception layer] collects the data, interacts with the environment, and consists of devices using light, sound, motion, air quality and temperature sensors.
\item [Network layer] replays the communication messages between the sensor nodes and the server through protocols such as \gls{MQTT}.
\begin{landscape}
\begin{figure}
- \includegraphics[width=\linewidth]{arch}
+ \includegraphics[width=.95\linewidth]{arch}
\caption{%
- \gls{PRS} and \gls{PWS} (left) together with \gls{CRS} and \gls{PRS} (right) mapped to the four-tier \gls{IOT} architecture.
+ \begin{sloppypar}
+ \Gls{PRS} and \gls{PWS} (left) together with \gls{CRS} and \gls{PRS} (right) mapped to the four-tier \gls{IOT} architecture.
Every box is the diagram denotes a source file or base.
Bold blue text describes the language or technology used in that source.
The network and perception layer are unique to the specific implementation, where the application and presentation layers are shared between implementations.
+ \end{sloppypar}
}%
\label{fig_t4t:iot_arch}
\end{figure}
\end{landscape}
-\subsection{The benefits and challenges of developing tiered \texorpdfstring{\gls{IOT}}{IoT} stacks}
+\subsection{The benefits and challenges of developing tiered \texorpdfstring{\glsxtrshort{IOT}}{IoT} stacks}
Using multiple tiers to
structure complex software is a common software engineering practice that provides significant architectural benefits for \gls{IOT} and other software. The tiered \gls{PYTHON} \gls{PRS} and \gls{PWS} stacks exhibit these benefits.
-\begin{description}
+\begin{description}[style=sameline]
- \item[Modularity] tiers allow a system to be structured as a set of components with clearly defined functionality. They can be implemented independently, and may be interchanged with other components that have similar functionality~\citep{maccormack2007impact}. In \gls{PRS} and \gls{PWS}, for example, a different NoSQL DBMS could relatively easily be substituted for {MongoDB}.
+ \item[Modularity] tiers allow a system to be structured as a set of components with clearly defined functionality. They can be implemented independently, and may be interchanged with other components that have similar functionality \citep{maccormack2007impact}. In \gls{PRS} and \gls{PWS}, for example, a different NoSQL DBMS could relatively easily be substituted for {MongoDB}.
- \item[Abstraction] the hierarchical composition of components in the stack abstracts the view of the system as a whole. Enough detail is provided to understand the roles of each layer and how the components relate to one another~\citep{belle2013layered}. \Cref{fig_t4t:iot_arch} illustrates the abstraction of \gls{PRS} and \gls{PWS} into four tiers.
+ \item[Abstraction] the hierarchical composition of components in the stack abstracts the view of the system as a whole. Enough detail is provided to understand the roles of each layer and how the components relate to one another \citep{belle2013layered}. \Cref{fig_t4t:iot_arch} illustrates the abstraction of \gls{PRS} and \gls{PWS} into four tiers.
- \item[Cohesion] well-defined boundaries ensure each tier contains functionality directly related to the task of the component~\citep{lee2001component}. The tiers in \gls{PRS} and \gls{PWS} contain all the functionality associated with perception, networking, application and presentation respectively.
+ \item[Cohesion] well-defined boundaries ensure each tier contains functionality directly related to the task of the component \citep{lee2001component}. The tiers in \gls{PRS} and \gls{PWS} contain all the functionality associated with perception, networking, application and presentation respectively.
\end{description}
However, a tiered architecture poses significant challenges for developers of \gls{IOT} and other software. The tiered \gls{PYTHON} \gls{PRS} and \gls{PWS} stacks exhibit these challenges, and we analyse these in detail later in the paper.
-\begin{description}
- \item[Polyglot development] the developer must be fluent in all the languages and components in the stack, known as being a full-stack developer for webapps \citep{mazzei2018full}. That is, the developer must correctly use multiple languages that have different paradigms, i.e.\ manage significant \emph{semantic friction}~\citep{ireland2009classification}. For example the \gls{PWS} developer must integrate components written in seven languages with two paradigms (\cref{sec_t4t:interoperation}).
+\begin{description}[style=sameline]
+ \item[Polyglot development] the developer must be fluent in all the languages and components in the stack, known as being a full-stack developer for webapps \citep{mazzei2018full}. That is, the developer must correctly use multiple languages that have different paradigms, i.e.\ manage significant \emph{semantic friction} \citep{ireland2009classification}. For example the \gls{PWS} developer must integrate components written in seven languages with two paradigms (\cref{sec_t4t:interoperation}).
\item[Correct interoperation] the developer must adhere to the \gls{API} or communication protocols between components. \Cref{sec_t4t:codesize,sec_t4t:resourcerich} show that communication requires some 17\% of \gls{PRS} and \gls{PWS} code, so around 100 \gls{SLOC}. \Cref{sec_t4t:Communication} discusses the complexity of writing this distributed communication code.
\item[Maintaining type safety] is a key element of the semantic friction encountered in multi-language stacks, and crucial for correctness. The developer must maintain type safety across a range of very different languages and diverse type systems, with minimal tool support. We show an example where \gls{PRS} loses type safety over the network layer (\Cref{sec_t4t:typesafety}).
\item[Managing multiple failure modes] different components may have different failure modes, and these must be coordinated. \Cref{sec_t4t:NetworkManagement} outlines how \gls{PRS} and \gls{PWS} use heartbeats to manage failures.
\end{description}
-Beyond \gls{PRS} and \gls{PWS} the challenges of tiered polyglot software development are evidenced in real world studies. As recent examples, a study of GitHub open source projects found an average of five different languages in each project, with many using tiered architectures~\citep{mayer2017multi}.
-An earlier empirical study of GitHub shows that using more languages to implement a project has a significant effect on project quality, since it increases defects~\citep{kochhar2016large}.
-A study of \gls{IOT} stack developers found that interoperation poses a real challenge, that microservices blur the abstraction between tiers, and that both testing and scaling \gls{IOT} applications to more devices are hard~\citep{motta2018challenges}.
+Beyond \gls{PRS} and \gls{PWS} the challenges of tiered polyglot software development are evidenced in real world studies. As recent examples, a study of GitHub open source projects found an average of five different languages in each project, with many using tiered architectures \citep{mayer2017multi}.
+An earlier empirical study of GitHub shows that using more languages to implement a project has a significant effect on project quality, since it increases defects \citep{kochhar2016large}.
+A study of \gls{IOT} stack developers found that interoperation poses a real challenge, that microservices blur the abstraction between tiers, and that both testing and scaling \gls{IOT} applications to more devices are hard \citep{motta2018challenges}.
One way of minimising the challenges of developing tiered polyglot \gls{IOT} software is to standardise and reuse components. This approach has been hugely successful for web stacks, e.g.\ browser standards. The W3C
-Web of Things aims to facilitate re-use by providing standardised metadata and other re-usable technological \gls{IOT} building blocks~\citep{guinard_building_2016}. However, the Web of Things has yet to gain widespread adoption. Moreover, as it is based on web technology, it requires the \emph{thing} to run a web server, significantly increasing the hardware requirements.
+Web of Things aims to facilitate re-use by providing standardised metadata and other re-usable technological \gls{IOT} building blocks \citep{guinard_building_2016}. However, the Web of Things has yet to gain widespread adoption. Moreover, as it is based on web technology, it requires the \emph{thing} to run a web server, significantly increasing the hardware requirements.
\section{Tierless languages}%
\label{sec_t4t:TiredvsTierless}
A radical approach to overcoming the challenges raised by tiered distributed software is to use a tierless programming language that eliminates the semantic friction between tiers by generating code for all tiers, and all communication between tiers, from a single program.
-%\adriancomment{Also referred to as multi-tier programming, tierless language applications usually utilise a single language, paradigm and type system, and the entire system is simultaneously checked by the compiler~\citep{weisenburger2020survey}.}
+%\adriancomment{Also referred to as multi-tier programming, tierless language applications usually utilise a single language, paradigm and type system, and the entire system is simultaneously checked by the compiler \citep{weisenburger2020survey}.}
Typically a tierless program uses a single language, paradigm and type system, and the entire distributed system is simultaneously checked by the compiler.
There is intense interest in developing tierless, or multitier, language technologies with a number of research languages developed over the last fifteen years, e.g.\ \citep{cooper2006links, serrano2006hop, troyer_building_2018, 10.1145/2775050.2633367}. These languages demonstrate the
advantages of the paradigm, including less development effort, better maintainability, and sound semantics of distributed execution. At the same time a number of industrial technologies incorporate tierless concepts, e.g.\ \citep{balat2006ocsigen, bjornson2010composing, strack2015getting}. These languages demonstrate the benefits of the paradigm in practice. Some tierless languages use (embedded) \glspl{DSL} to specify parts of the multi-tier software.
-Tierless languages have been developed for a range of distributed paradigms, including web applications, client-server applications, mobile applications, and generic distributed systems. A recent and substantial survey of these tierless technologies is available~\citep{weisenburger2020survey}. Here we provide a brief introduction to tierless languages with a focus on \gls{IOT} software.
+Tierless languages have been developed for a range of distributed paradigms, including web applications, client-server applications, mobile applications, and generic distributed systems. A recent and substantial survey of these tierless technologies is available \citep{weisenburger2020survey}. Here we provide a brief introduction to tierless languages with a focus on \gls{IOT} software.
\subsection{Tierless web languages}
% Standalone DSLs
There are established tierless languages for web development, both standalone languages and \glspl{DSL} embedded in a host language.
-Example standalone tierless web languages are Links~\citep{cooper2006links} and Hop~\citep{serrano2006hop}.
+Example standalone tierless web languages are Links \citep{cooper2006links} and Hop \citep{serrano2006hop}.
From a single declarative program the client, server and database code is simultaneously checked by the compiler, and compiled to the required component languages. For example, Links compiles to HTML and JavaScript for the client side and to SQL on the server-side to interact with the database system.
-An example tierless web framework that uses a \gls{DSL} is Haste~\citep{10.1145/2775050.2633367}, that embeds the \gls{DSL} in \gls{HASKELL}. Haste programs are compiled multiple times: the server code is generated by the standard \gls{GHC} \gls{HASKELL} compiler~\citep{hall1993glasgow}; Javascript for the client is generated by a custom \gls{GHC} compiler backend. The design leverages \gls{HASKELL}'s high-level programming abstractions and strong typing, and benefits from \gls{GHC}: a mature and sophisticated compiler.
+An example tierless web framework that uses a \gls{DSL} is Haste \citep{10.1145/2775050.2633367}, that embeds the \gls{DSL} in \gls{HASKELL}. Haste programs are compiled multiple times: the server code is generated by the standard \gls{GHC} \gls{HASKELL} compiler \citep{hall1993glasgow}; Javascript for the client is generated by a custom \gls{GHC} compiler backend. The design leverages \gls{HASKELL}'s high-level programming abstractions and strong typing, and benefits from \gls{GHC}: a mature and sophisticated compiler.
-\subsection{Tierless \texorpdfstring{\gls{IOT}}{IoT} languages}
+\subsection{Tierless \texorpdfstring{\glsxtrshort{IOT}}{IoT} languages}
The use of tierless languages in \gls{IOT} applications is both more recent and less common than for web applications.
Tierless \gls{IOT} programming may extend tierless web programming by adding network and perception layers.
The presentation layer of a tierless \gls{IOT} language, like tierless web languages, benefits from almost invariably executing in a standard browser. The perception layer faces greater challenges, often executing on one of a set of slow and resource-constrained microprocessors. Hence, tierless \gls{IOT} languages typically compile the perception layer to either \gls{C}\slash\gls{CPP} (the lingua franca of microcontrollers), or to some intermediate representation to be interpreted.
-\subsubsection{\texorpdfstring{\Glspl{DSL}}{DSLs} for microprocessors}
+\subsubsection{\texorpdfstring{\Glsxtrlongpl{DSL}}{DSLs} for microprocessors}
Many \glspl{DSL} provide high-level programming for microprocessors, for example providing strong typing and 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 \gls{C}\slash\gls{CPP}. In contrast to \gls{CLEAN}/\gls{ITASK}/\gls{MTASK} such \glspl{DSL} are not tierless \gls{IOT} languages as they have no automatic integration with the server, i.e.\ with the application and presentation layers.
+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 \gls{C}\slash\gls{CPP}. In contrast to \gls{CLEAN}/\gls{ITASK}/\gls{MTASK} such \glspl{DSL} are not tierless \gls{IOT} languages as they have no automatic integration with the server, i.e.\ with the application and presentation layers.
-\subsubsection{\texorpdfstring{\Gls{FRP}}{Functional reactive programming}}
+\subsubsection{\texorpdfstring{\Glsxtrlong{FRP}}{Functional reactive programming}}
\Gls{FRP} is a declarative paradigm often used for implementing the perception layer of an \gls{IOT} stack.
-Examples include 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}, and Haski~\citep{valliappan_towards_2020}.
+Examples include 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}, and Haski \citep{valliappan_towards_2020}.
None of these languages are tierless \gls{IOT} languages as they have no automatic integration with the server.
-Potato goes beyond other \gls{FRP} languages to provide a tierless \gls{FRP} \gls{IOT} language for resource rich sensor nodes~\citep{troyer_building_2018}. It does so using the Erlang programming language and sophisticated virtual machine.
+Potato goes beyond other \gls{FRP} languages to provide a tierless \gls{FRP} \gls{IOT} language for resource rich sensor nodes \citep{troyer_building_2018}. It does so using the Erlang programming language and sophisticated virtual machine.
-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}.
+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}.
-\subsubsection{Erlang/Elixir \texorpdfstring{\gls{IOT}}{IoT} systems}
+\subsubsection{Erlang/Elixir \texorpdfstring{\glsxtrshort{IOT}}{IoT} systems}
A number of production \gls{IOT} systems are engineered in Erlang or Elixir, and many are mostly tierless.
That is the perception, network and application layers are sets of distributed Erlang processes, although the presentation layer typically uses some conventional web technology.
A resource-rich sensor node may support many Erlang processes on an Erlang VM, or low level code (typically \gls{C}\slash\gls{CPP}) on a resource-constrained microprocessor can emulate an Erlang process.
-Only a small fraction of these systems are described in the academic literature, example exceptions are~\citep{sivieri2012drop,shibanai_distributed_2018}, with many described only in grey literature or not at all.
+Only a small fraction of these systems are described in the academic literature, example exceptions are \citep{sivieri2012drop,shibanai_distributed_2018}, with many described only in grey literature or not at all.
-\subsection{Characteristics of tierless \texorpdfstring{\gls{IOT}}{IoT} languages}%
+\subsection{Characteristics of tierless \texorpdfstring{\glsxtrshort{IOT}}{IoT} languages}%
\label{sec_t4t:characteristics}
-This study compares a pair of tierless \gls{IOT} languages with conventional tiered \gls{PYTHON} \gls{IOT} software. \gls{CLEAN}\slash\gls{ITASK} and \gls{CLEAN}/\gls{ITASK}/\gls{MTASK} represent a specific set of tierless language design decisions, however many alternative designs are available. Crucially the limitations of the tierless \gls{CLEAN} languages, e.g.\ that they currently provide limited security, should not be seen as limitations of tierless technologies in general. This section briefly outlines key design decisions for tierless \gls{IOT} languages, discusses alternative designs, and describes the \gls{CLEAN} designs. The \gls{CLEAN} designs are illustrated in the examples in the following section.
+This study compares a pair of tierless \gls{IOT} languages with conventional tiered \gls{PYTHON} \gls{IOT} software. \Gls{CLEAN}\slash\gls{ITASK} and \gls{CLEAN}/\gls{ITASK}/\gls{MTASK} represent a specific set of tierless language design decisions, however many alternative designs are available. Crucially the limitations of the tierless \gls{CLEAN} languages, e.g.\ that they currently provide limited security, should not be seen as limitations of tierless technologies in general. This section briefly outlines key design decisions for tierless \gls{IOT} languages, discusses alternative designs, and describes the \gls{CLEAN} designs. The \gls{CLEAN} designs are illustrated in the examples in the following section.
\subsubsection{Tier splitting and placement}
It is even possible to infer the splitting, relieving the developers from the need to specify it, as illustrated for Javascript as a tierless web language \citep{10.1145/2661136.2661146}.
In \gls{CLEAN}\slash\gls{ITASK}\slash\gls{MTASK} and \gls{CLEAN}\slash\gls{ITASK} tier splitting is specified by functions, e.g.\ the \gls{CLEAN}\slash\gls{ITASK} \cleaninline{asyncTask} function identifies a task for execution on a remote device and \cleaninline{liftmTask} executes the given task on an \gls{IOT} device.
-The tier splitting functions are illustrated in examples in the next section, e.g.\ on \cref{lst_tvtitaskTempFull:startdevtask} in \cref{lst_tvtitaskTempFull} and \cref{lst_tvtmtasktemp:liftmtask} in \cref{lst_tvtmtasktemp}.
+The tier splitting functions are illustrated in examples in the next section, e.g.\ on \cref{lst_t4t:itaskTempFull:startdevtask} in \cref{lst_t4t:itaskTempFull} and \cref{lst_t4t:mtasktemp:liftmtask} in \cref{lst_t4t:mtasktemp}.
Specifying splitting as functions means that new splitting functions can be composed, and that splitting is under program control, e.g.\ during execution a program can decide to run a task locally or remotely.
As \gls{IOT} stacks are more complex than web stacks, the \emph{placement} of data and computations onto the devices/hosts in the system is more challenging.
In \gls{CLEAN}\slash\gls{ITASK}\slash\gls{MTASK} sensor nodes are programmed once with the \gls{MTASK} \gls{RTS}, and possibly some precompiled tasks.
Thereafter a sensor node can dynamically receive \gls{MTASK} programs, compiled at runtime by the server.
In \gls{CLEAN}\slash\gls{ITASK} the sensor node runs an \gls{ITASK} server that recieves and executes code from the (\gls{IOT}) server \citep{oortgiese_distributed_2017}.
-Placement happens automatically as part of the first-class splitting constructs, so \cref{lst_tvtmtasktemp:liftmtask} in \cref{lst_tvtmtasktemp} places \cleaninline{devTask} onto the \cleaninline{dev} sensor node.
+Placement happens automatically as part of the first-class splitting constructs, so \cref{lst_t4t:mtasktemp:liftmtask} in \cref{lst_t4t:mtasktemp} places \cleaninline{devTask} onto the \cleaninline{dev} sensor node.
%\subsubsection{Program splitting}
%
%A key challenge for an automatically segmented tierless language is to determine which parts of the program correspond to a particular tier and hence should be executed by a specific component on a specific host, so-called tier splitting.
-%For example a tierless web language must identify client code to ship to browsers, database code to execute in the DBMS, and application code to run on the server. Some tierless languages split programs using types, others use syntactic markers, e.g.\ pragmas like \cleaninline{server} or \cleaninline{client}, to split the program~\citep{cooper2006links,10.1145/2775050.2633367}. It may be possible to infer the splitting between tiers, relieving the developers from the need specify it, as illustrated for Javascript as a tierless web language~\citep{10.1145/2661136.2661146}.
+%For example a tierless web language must identify client code to ship to browsers, database code to execute in the DBMS, and application code to run on the server. Some tierless languages split programs using types, others use syntactic markers, e.g.\ pragmas like \cleaninline{server} or \cleaninline{client}, to split the program \citep{cooper2006links,10.1145/2775050.2633367}. It may be possible to infer the splitting between tiers, relieving the developers from the need specify it, as illustrated for Javascript as a tierless web language \citep{10.1145/2661136.2661146}.
%
%In \gls{CLEAN}\slash\gls{ITASK}/\gls{MTASK} and \gls{CLEAN}/\gls{ITASK} tier splitting is specified by functions, and hence is a first-class language construct.
-%For example in \gls{CLEAN}\slash\gls{ITASK} the \cleaninline{asyncTask} function identifies a task for execution on a remote device and \cleaninline{liftmTask} executes the given task on an \gls{IOT} device. The tier splitting functions are illustrated in examples in the next section, e.g.\ on \cref{lst_t4t:itaskTempFull:startdevtask} in \cref{lst_t4t:itaskTempFull} and \cref{lst_t4t:mtaskTemp:liftmtask} in \cref{lst_t4t:mtaskTemp}.
+%For example in \gls{CLEAN}\slash\gls{ITASK} the \cleaninline{asyncTask} function identifies a task for execution on a remote device and \cleaninline{liftmTask} executes the given task on an \gls{IOT} device. The tier splitting functions are illustrated in examples in the next section, e.g.\ on \cref{lst_t4t:itaskTempFull:startdevtask} in \cref{lst_t4t:itaskTempFull} and \cref{lst_t4t:mtasktemp:liftmtask} in \cref{lst_t4t:mtasktemp}.
%Specifying splitting as functions means that new splitting functions can be composed, and that splitting is under program control, e.g.\ during execution a program can decide to run a task locally or remotely.
\subsubsection{Communication}\label{ssec_t4t:communication}
-Tierless languages may adopt a range of communication paradigms for communicating between components. Different tierless languages specify communication in different ways~\citep{weisenburger2020survey}. Remote procedures are the most common communication mechanism: a procedure/function executing on a remote host/machine is called as if it was local. The communication of the arguments to, and the results from, the remote procedure is automatically provided by the language implementation. Other mechanisms include explicit message passing between components; publish/subscribe where components subscribe to topics of interest from other components; reactive programming defines event streams between remote components; finally shared state makes changes in a shared and potentially remote data structure visible to components.
+Tierless languages may adopt a range of communication paradigms for communicating between components. Different tierless languages specify communication in different ways \citep{weisenburger2020survey}. Remote procedures are the most common communication mechanism: a procedure/function executing on a remote host/machine is called as if it was local. The communication of the arguments to, and the results from, the remote procedure is automatically provided by the language implementation. Other mechanisms include explicit message passing between components; publish/subscribe where components subscribe to topics of interest from other components; reactive programming defines event streams between remote components; finally shared state makes changes in a shared and potentially remote data structure visible to components.
\Gls{CLEAN}\slash\gls{ITASK}/\gls{MTASK} and \gls{CLEAN}/\gls{ITASK} communicate using a combination of remote task invocation, similar to remote procedures, and shared state through \glspl{SDS}.
\Cref{lst_t4t:itaskTempFull} illustrates: \cref{lst_t4t:itaskTempFull:startdevtask} shows a server task launching a remote task, \cleaninline{devTask}, on to a sensor node; and \cref{lst_t4t:itaskTempFull:remoteShare} shows the sharing of the remote \cleaninline{latestTemp} \gls{SDS}.
%Techniques such as over-the-air programming and interpreters allow microprocessors to be dynamically provisioned, increasing their maintainability and resilience.
%For example \citet{baccelli_reprogramming_2018} provide a single language \gls{IOT} system based on the RIOT \gls{OS} that allows runtime deployment of code snippets called containers.
%Both client and server are written in JavaScript. However, there is no integration between the client and the server other than that they are programmed from a single source.
-%Mat\`e is an example of an early tierless sensor network framework where devices are provided with a virtual machine using TinyOS for dynamic provisioning~\citep{levis_mate_2002}.
+%Mat\`e is an example of an early tierless sensor network framework where devices are provided with a virtual machine using TinyOS for dynamic provisioning \citep{levis_mate_2002}.
%
%Placement specifies how data and computations in a tierless program are assigned to the
-%devices/hosts in the distributed system. Different tierless languages specify placement in different ways, e.g.\ code annotations or configuration files, and at different granularities, e.g.\ per function or per class~\citep{weisenburger2020survey}.
+%devices/hosts in the distributed system. Different tierless languages specify placement in different ways, e.g.\ code annotations or configuration files, and at different granularities, e.g.\ per function or per class \citep{weisenburger2020survey}.
%
%\Gls{CLEAN}\slash\gls{ITASK}/\gls{MTASK} and \gls{CLEAN}/\gls{ITASK} both use dynamic task placement, similar to dynamic function placement.
%In \gls{CLEAN}\slash\gls{ITASK}/\gls{MTASK} sensor nodes are programmed once with the \gls{MTASK} \gls{RTS}, and possibly some precompiled tasks.
%Thereafter a sensor node can dynamically receive \gls{MTASK} programs, compiled at runtime by the server.
-%In \gls{CLEAN}\slash\gls{ITASK} the sensor node runs an \gls{ITASK} server that recieves and executes code from the (\gls{IOT}) server~\citep{oortgiese_distributed_2017}.
-%%The \gls{ITASK} server decides what code to execute depending on the serialised execution graph that the server sends~\citep{oortgiese_distributed_2017}.
-%Placement happens automatically as part of the first-class splitting constructs outlined in \cref{ssec_t4t:communication}, so \cref{lst_t4t:mtaskTemp:liftmtask} in \cref{lst_t4t:mtaskTemp} places \cleaninline{devTask} onto the \cleaninline{dev} sensor node.
+%In \gls{CLEAN}\slash\gls{ITASK} the sensor node runs an \gls{ITASK} server that recieves and executes code from the (\gls{IOT}) server \citep{oortgiese_distributed_2017}.
+%%The \gls{ITASK} server decides what code to execute depending on the serialised execution graph that the server sends \citep{oortgiese_distributed_2017}.
+%Placement happens automatically as part of the first-class splitting constructs outlined in \cref{ssec_t4t:communication}, so \cref{lst_t4t:mtasktemp:liftmtask} in \cref{lst_t4t:mtasktemp} places \cleaninline{devTask} onto the \cleaninline{dev} sensor node.
\subsubsection{Security}
-Security is a major issue and a considerable challenge for many \gls{IOT} systems~\citep{10.1145/3437537}. There are potentially security issues at each layer in an \gls{IOT} application (\cref{fig_t4t:iot_arch}). The security issues and defence mechanisms at the application and presentation layers are relatively standard, e.g.\ defending against SQL injection attacks. The security issues at the network and perception layers are more challenging. Resource-rich sensor nodes can adopt some standard security measures like encrypting messages, and regularly applying software patches to the operating system. However microprocessors often lack the computational resources for encryption, and it is hard to patch their system software because the program is often stored in flash memory. In consequence there are infamous examples of \gls{IOT} systems being hijacked to create botnets~\citep{203628,herwig_measurement_2019}.
+Security is a major issue and a considerable challenge for many \gls{IOT} systems \citep{10.1145/3437537}. There are potentially security issues at each layer in an \gls{IOT} application (\cref{fig_t4t:iot_arch}). The security issues and defence mechanisms at the application and presentation layers are relatively standard, e.g.\ defending against SQL injection attacks. The security issues at the network and perception layers are more challenging. Resource-rich sensor nodes can adopt some standard security measures like encrypting messages, and regularly applying software patches to the operating system. However microprocessors often lack the computational resources for encryption, and it is hard to patch their system software because the program is often stored in flash memory. In consequence there are infamous examples of \gls{IOT} systems being hijacked to create botnets \citep{203628,herwig_measurement_2019}.
Securing the entire stack in a conventional tiered \gls{IOT} application is particularly challenging as the stack is implemented in a collection of programming languages with low level programming and communication abstractions. In such polyglot distributed systems it is hard to determine, and hence secure, the flow of data between components. In consequence a small mistake may have severe security implications.
-A number of characteristics of tierless languages help to improve security. Communication and placement vulnerabilities are minimised as communication and placement are automatically generated and checked by the compiler. So injection attacks and the exploitation of communication/placement protocol bugs are less likely. Vulnerabilities introduced by mismatched types are avoided as the entire system is type checked. Moreover, tierless languages can exploit language level security techniques. For example languages like Jif/split~\citep{zdancewic2002secure} and Swift~\citep{chong2007secure} place components to protect the security of data. Another example are programming language technologies for controlling information flow, and these can be used to improve security. For example Haski uses them to improve the security of \gls{IOT} systems~\citep{valliappan_towards_2020}.
+A number of characteristics of tierless languages help to improve security. Communication and placement vulnerabilities are minimised as communication and placement are automatically generated and checked by the compiler. So injection attacks and the exploitation of communication/placement protocol bugs are less likely. Vulnerabilities introduced by mismatched types are avoided as the entire system is type checked. Moreover, tierless languages can exploit language level security techniques. For example languages like Jif/split \citep{zdancewic2002secure} and Swift \citep{chong2007secure} place components to protect the security of data. Another example are programming language technologies for controlling information flow, and these can be used to improve security. For example Haski uses them to improve the security of \gls{IOT} systems \citep{valliappan_towards_2020}.
-However many tierless languages have yet to provide a comprehensive set of security technologies, despite its importance in domains like web and \gls{IOT} applications. For example Erlang and many Erlang-based systems~\citep{shibanai_distributed_2018,sivieri2012drop}, lack important security measures. Indeed security is not covered in a recent, otherwise comprehensive, survey of tierless technologies~\citep{weisenburger2020survey}.
+However many tierless languages have yet to provide a comprehensive set of security technologies, despite its importance in domains like web and \gls{IOT} applications. For example Erlang and many Erlang-based systems \citep{shibanai_distributed_2018,sivieri2012drop}, lack important security measures. Indeed security is not covered in a recent, otherwise comprehensive, survey of tierless technologies \citep{weisenburger2020survey}.
-\Gls{CLEAN}\slash\gls{ITASK} and \gls{CLEAN}/\gls{ITASK}/\gls{MTASK} are typical in this respect: little effort has yet been expended on improving their security. Of course as tierless languages they benefit from static type safety and automatically generated communication and placement. Some preliminary work shows that, as the communication between layers is protocol agnostic, more secure alternatives can be used. One example is to run the \gls{ITASK} server behind a reverse proxy implementing TLS/SSL encryption~\citep{wijkhuizen_security_2018}. A second is to add integrity checks or even encryption to the communication protocol for resource-rich sensor nodes~\citep{boer_de_secure_2020}.
+\Gls{CLEAN}\slash\gls{ITASK} and \gls{CLEAN}/\gls{ITASK}/\gls{MTASK} are typical in this respect: little effort has yet been expended on improving their security. Of course as tierless languages they benefit from static type safety and automatically generated communication and placement. Some preliminary work shows that, as the communication between layers is protocol agnostic, more secure alternatives can be used. One example is to run the \gls{ITASK} server behind a reverse proxy implementing TLS/SSL encryption \citep{wijkhuizen_security_2018}. A second is to add integrity checks or even encryption to the communication protocol for resource-rich sensor nodes \citep{boer_de_secure_2020}.
-\section{Task-oriented and \texorpdfstring{\gls{IOT}}{IoT} programming in \texorpdfstring{\gls{CLEAN}}{Clean}}
+\section{Task-oriented and \texorpdfstring{\glsxtrshort{IOT}}{IoT} programming in \texorpdfstring{\glsentrytext{CLEAN}}{Clean}}
To make this paper self-contained we provide a concise overview of \gls{CLEAN}, \gls{TOP}, and \gls{IOT} programming in \gls{ITASK} and \gls{MTASK}. The minor innovations reported here are the interface to the \gls{IOT} sensors, and the \gls{CLEAN} port for the Raspberry Pi.
-\Gls{CLEAN} is a statically typed \gls{FP} language similar to \gls{HASKELL}: both languages are pure and non-strict~\citep{achten_clean_2007}.
-A key difference is how state is handled: \gls{HASKELL} typically embeds stateful actions in the \haskellinline{IO} Monad~\citep{peyton_jones_imperative_1993,wiki:IO}.
-In contrast, \gls{CLEAN} has a uniqueness type system to ensure the single-threaded use of stateful objects like files and windows~\citep{barendsen_smetsers_1996}.
-Both \gls{CLEAN} and \gls{HASKELL} support fairly similar models of generic programming~\citep{ComparingGenericProgramming}, enabling functions to work on many types. As we shall see generic programming is heavily used in task-oriented programming~\citep{GenericProgrammingExtensionForClean,HinzeGenericFunctionalProgramming}, for example to construct web editors and communication protocols that work for any user-defined datatype.
+\Gls{CLEAN} is a statically typed \gls{FP} language similar to \gls{HASKELL}: both languages are pure and non-strict \citep{achten_clean_2007}.
+A key difference is how state is handled: \gls{HASKELL} typically embeds stateful actions in the \haskellinline{IO} Monad \citep{peyton_jones_imperative_1993,wiki:IO}.
+In contrast, \gls{CLEAN} has a uniqueness type system to ensure the single-threaded use of stateful objects like files and windows \citep{barendsen_smetsers_1996}.
+Both \gls{CLEAN} and \gls{HASKELL} support fairly similar models of generic programming \citep{ComparingGenericProgramming}, enabling functions to work on many types. As we shall see generic programming is heavily used in task-oriented programming \citep{GenericProgrammingExtensionForClean,HinzeGenericFunctionalProgramming}, for example to construct web editors and communication protocols that work for any user-defined datatype.
\subsection{\texorpdfstring{\Glsxtrlong{TOP}}{Task-oriented programming}}
-\Gls{TOP} is a declarative programming paradigm for constructing interactive distributed systems~\citep{plasmeijer_task-oriented_2012}.
+\Gls{TOP} is a declarative programming paradigm for constructing interactive distributed systems \citep{plasmeijer_task-oriented_2012}.
Tasks are the basic blocks of \gls{TOP} and represent work that needs to be done in the broadest sense.
Examples of typical tasks range from allowing a user to complete a form, controlling peripherals, moderating other tasks, or monitoring a database.
From a single declarative description of tasks all of the required software components are generated.
This may include web servers, client code for browsers or \gls{IOT} devices, and for their interoperation.
That is, from a single \gls{TOP} program the language implementation automatically generates an \emph{integrated distributed system}.
-Application areas range from simple web forms or blinking \glspl{LED} to multi-user distributed collaboration between people and machines~\citep{oortgiese_distributed_2017}.
+Application areas range from simple web forms or blinking \glspl{LED} to multi-user distributed collaboration between people and machines \citep{oortgiese_distributed_2017}.
\Gls{TOP} adds three concepts: tasks, task combinators, and \glspl{SDS}. Example basic tasks are web editors for user-defined datatypes, reading some \gls{IOT} sensor, or controlling peripherals like a servo motor.
Task combinators compose tasks into more advanced tasks, either in parallel or sequential and allow task values to be observed by other tasks.
As tasks can be returned as the result of a function, recursion can be freely used, e.g.\ to express the repetition of tasks.
There are also standard combinators for common patterns.
-Tasks can exchange information via \glspl{SDS}~\citep{ParametricLenses}.
+Tasks can exchange information via \glspl{SDS} \citep{ParametricLenses}.
All tasks involved can atomically observe and change the value of a typed \gls{SDS}, allowing more flexible communication than with task combinators.
\Glspl{SDS} offer a general abstraction of data shared by different tasks, analogous to variables, persistent values, files, databases and peripherals like sensors. Combinators compose \glspl{SDS} into a larger \gls{SDS}, and
parametric lenses define a specific view on an \gls{SDS}.
-\subsection{The \texorpdfstring{\gls{ITASK}}{iTask} \texorpdfstring{\gls{EDSL}}{eDSL}}%
+\subsection{The \texorpdfstring{\glsentrytext{ITASK}}{iTask} \texorpdfstring{\glsxtrlong{EDSL}}{eDSL}}%
\label{sec_t4t:itasks}
-The \gls{ITASK} \gls{EDSL} is designed for constructing multi-user distributed applications, including web~\citep{TOP-ICFP07} or \gls{IOT} applications.
+The \gls{ITASK} \gls{EDSL} is designed for constructing multi-user distributed applications, including web \citep{TOP-ICFP07} or \gls{IOT} applications.
Here we present \gls{ITASK} by example, and the first is a complete program to repeatedly read the room temperature from a digital humidity and temperature (DHT) sensor attached to the machine and display it on a web page (\cref{lst_t4t:itaskTemp}).
The first line is the module name, the third imports the \cleaninline{iTask} module, and the main function (\cref{lst_t4t:itaskTemp:systemfro,lst_t4t:itaskTemp:systemto}) launches \cleaninline{readTempTask} and the \gls{ITASK} system to generate the web interface in \cref{fig_t4t:itaskTempSimple}.
-Interaction with a device like the DHT sensor using a protocol like 1-Wire or gls{I2C} is abstracted into a library. So the \cleaninline{readTempTask} task starts by creating a \cleaninline{dht} sensor object (\cref{lst_t4t:itaskTemp:dhtDef}) thereafter \cleaninline{repeatEvery} executes a task at the specified \cleaninline{interval}. This task reads the temperature from the \cleaninline{dht} sensor, and with a sequential composition combinator \cleaninline{>>~} passes the \cleaninline{temp} value to \cleaninline{viewInformation} that displays it on the web page (\cref{lst_t4t:itaskTemp:viewInformation}).
+Interaction with a device like the DHT sensor using a protocol like 1-Wire or \gls{I2C} is abstracted into a library. So the \cleaninline{readTempTask} task starts by creating a \cleaninline{dht} sensor object (\cref{lst_t4t:itaskTemp:dhtDef}) thereafter \cleaninline{repeatEvery} executes a task at the specified \cleaninline{interval}. This task reads the temperature from the \cleaninline{dht} sensor, and with a sequential composition combinator \cleaninline{>>~} passes the \cleaninline{temp} value to \cleaninline{viewInformation} that displays it on the web page (\cref{lst_t4t:itaskTemp:viewInformation}).
The tuning combinator \cleaninline{<<@} adds a label to the web editor displaying the temperature. Crucially, the \gls{ITASK} implementation transparently ships parts of the code for the web-interface to be executed in the browser, and \cref{fig_t4t:itaskTempSimple} shows the UML deployment diagram.
\begin{lstClean}[%
temperature dht >>* [+\label{lst_t4t:itaskTemp:step}+]
[ OnValue (ifValue ((<>) old) \temp -> [+\label{lst_t4t:itaskTemp:action1}+]
get currentTime >>~ \time ->
- upd (\list.[{time=time, temp=temp}:list]) measurementsSDS
+ upd (\list -> [{time = time, temp = temp}:list]) measurementsSDS
@! temp)
, OnValue (always (waitForTimer False interval @! old))[+\label{lst_t4t:itaskTemp:action2}+]
] >>~ task
((Label "# to take" @>> enterInformation []) -|| [+\label{lst_t4t:itaskTemp:enter}+]
(Label "Measurements" @>> [+\label{lst_t4t:itaskTemp:view}+]
viewSharedInformation
- [ ViewAs (if byTemp (sortBy (\x y->x.temp < y.temp)) id)]
+ [ ViewAs (if byTemp (sortBy (\x y -> x.temp < y.temp)) id)]
measurementsSDS)) >>*[+\label{lst_t4t:itaskTemp:viewend}+]
[ OnAction (Action "Clear") (always
(set [] measurementsSDS >-| controlSDS byTemp))
, OnAction (Action "Take") (ifValue ((<) 0)
- (\n.upd (take n) measurementsSDS >-| controlSDS byTemp))
+ (\n -> upd (take n) measurementsSDS >-| controlSDS byTemp))
, OnAction (Action (if byTemp "Sort time" "Sort temp")) (always
(controlSDS (not byTemp)))
] [+\label{lst_t4t:itaskTemp:actionend}+]
\Cref{fig_t4t:TempHistory} shows two screenshots of web pages generated by the \cleaninline{TempHistory} program. \Cref{fig_t4t:TempHistoryDiagram} is the deployment diagram showing the addition of the persistent \cleaninline{measurementsSDS} that stores the history of temperature measurements.
-\subsection{Engineering tierless \texorpdfstring{\gls{IOT}}{IoT} systems with \texorpdfstring{\gls{ITASK}}{iTask}}%
+\subsection{Engineering tierless \texorpdfstring{\glsxtrshort{IOT}}{IoT} systems with \texorpdfstring{\glsentrytext{ITASK}}{iTask}}%
\label{sec_t4t:itaskIOT}
A typical \gls{IOT} system goes beyond a web application by incorporating a distributed set of sensor nodes each with a collection of sensors or actuators. That is, they add the perception and network layers in \cref{fig_t4t:iot_arch}. If the sensor nodes have the computational resources to support an \gls{ITASK} server, as a Raspberry Pi does, then \gls{ITASK} can also be used to implement these layers, and integrate them with the application and presentation layers tierlessly.
tempSDS = sharedStore "temperatures" []
latestTemp :: SDSLens () (? (DateTime, Real)) (DateTime, Real)
-latestTemp = mapReadWrite (listToMaybe, \x xs-> ?Just [x:xs]) ?None tempSDS
+latestTemp = mapReadWrite (listToMaybe, \x xs -> ?Just [x:xs]) ?None tempSDS
devTask :: Task DateTime
devTask = [+\label{lst_t4t:itaskTempFull:sensorfro}+]
\label{fig_t4t:cwtsweb}
\end{figure}
-\subsection{The \texorpdfstring{\gls{MTASK}}{mTask} \texorpdfstring{\gls{EDSL}}{eDSL}}%
+\subsection{The \texorpdfstring{\glsentrytext{MTASK}}{mTask} \texorpdfstring{\glsxtrlong{EDSL}}{eDSL}}%
\label{sec_t4t:mtasks}
In many \gls{IOT} systems the sensor nodes are resource constrained, e.g.\ inexpensive microprocessors. These are far cheaper, and consume far less power, than a single-board computer like a Raspberry Pi. Microprocessors also allow the programmer to easily control peripherals like sensors and actuators via the \gls{IO} pins of the processor.
The \gls{MTASK} \gls{OS} is stored in flash memory while the tasks are stored in \gls{RAM} to minimise wear on the flash memory. While sending byte code to a sensor node at runtime greatly increases the amount of communication, this can be mitigated as any tasks known at compile time can be preloaded on the microprocessor.
In contrast, compiled programs, like \gls{C}\slash\gls{CPP}, are stored in flash memory and there can only ever be a few thousand programs uploaded during the lifetime of the microprocessor before exhausting the flash memory.
-\subsection{Engineering tierless \texorpdfstring{\gls{IOT}}{IoT} systems with \texorpdfstring{\gls{MTASK}}{mTask}}%
+\subsection{Engineering tierless \texorpdfstring{\glsxtrshort{IOT}}{IoT} systems with \texorpdfstring{\glsentrytext{MTASK}}{mTask}}%
\label{sec_t4t:mtaskIOT}
A tierless \gls{CLEAN} \gls{IOT} system with microprocessor sensor nodes integrates a set of \gls{ITASK} tasks that specify the application and presentation layers with a set of \gls{MTASK}s that specify the perception and network layers.
-We illustrate with \gls{CWTS}: a simple room temperature sensor with a web display. \gls{CWTS} is equivalent to the \gls{ITASK} \gls{CRTS} (\cref{lst_t4t:itaskTempFull}), except that the sensor node is a \gls{WEMOS} microprocessor.
+We illustrate with \gls{CWTS}: a simple room temperature sensor with a web display. \Gls{CWTS} is equivalent to the \gls{ITASK} \gls{CRTS} (\cref{lst_t4t:itaskTempFull}), except that the sensor node is a \gls{WEMOS} microprocessor.
-\Cref{lst_t4t:mtaskTemp} shows the complete program, and the key function is \cleaninline{devTask} with a top-level \cleaninline{Main} type (\cref{lst_t4t:mtaskTemp:devTask}). In \gls{MTASK} functions, shares, and devices can only be defined at this top level.
+\Cref{lst_t4t:mtasktemp} shows the complete program, and the key function is \cleaninline{devTask} with a top-level \cleaninline{Main} type (\cref{lst_t4t:mtasktemp:devTask}). In \gls{MTASK} functions, shares, and devices can only be defined at this top level.
The program uses the same shares \cleaninline{tempSDS} and~\cleaninline{latestTemp} as \gls{CRTS}, and for completeness we repeat those definitions.
-The body of \cleaninline{devTask} is the \gls{MTASK} slice of the program (\crefrange{lst_t4t:mtaskTemp:DHT}{lst_t4t:mtaskTemp:setSds}).
+The body of \cleaninline{devTask} is the \gls{MTASK} slice of the program (\crefrange{lst_t4t:mtasktemp:DHT}{lst_t4t:mtasktemp:setSds}).
With \cleaninline{DHT} we again create a temperature sensor object \cleaninline{dht}.
The \gls{ITASK} \gls{SDS} \cleaninline{latestTemp} is first transformed to a \gls{SDS} that accepts only temperature values,
the \cleaninline{dateTimeStampedShare} adds the data via a lens.
%The \cleaninline{mapRead} ensures that every write to \cleaninline{localSds} is automatically time-stamped when it is written to \cleaninline{latestTemp}.
-The \cleaninline{mainTask} is a simple \gls{ITASK} task that starts the \cleaninline{devTask} \gls{MTASK} task on the device identified by \cleaninline{deviceInfo} (\cref{lst_t4t:mtaskTemp:withdevice}). At runtime the \gls{MTASK} slice is compiled to byte code, shipped to the indicated device, and launched. Thereafter, \cleaninline{mainTask} reads temperature values from the \cleaninline{latestTemp} \gls{SDS} that is shared with the \gls{MTASK} device, and displays them on a web page (\cref{fig_t4t:cwtsweb}). The \gls{SDS}---shared with the device using \cleaninline{liftsds}---automatically communicates new temperature values from the microprocessor to the server.
+The \cleaninline{mainTask} is a simple \gls{ITASK} task that starts the \cleaninline{devTask} \gls{MTASK} task on the device identified by \cleaninline{deviceInfo} (\cref{lst_t4t:mtasktemp:withdevice}). At runtime the \gls{MTASK} slice is compiled to byte code, shipped to the indicated device, and launched. Thereafter, \cleaninline{mainTask} reads temperature values from the \cleaninline{latestTemp} \gls{SDS} that is shared with the \gls{MTASK} device, and displays them on a web page (\cref{fig_t4t:cwtsweb}). The \gls{SDS}---shared with the device using \cleaninline{liftsds}---automatically communicates new temperature values from the microprocessor to the server.
While this simple application makes limited use of the \gls{MTASK} \gls{EDSL}, it illustrates some powerful \gls{MTASK} program abstractions like basic tasks, task combinators, named recursive and parameterized tasks, and \glspl{SDS}.
-Function composition (\cref{lst_t4t:mtaskTemp:o}) and currying (\cref{lst_t4t:mtaskTemp:setSds}) are inherited from the \gls{CLEAN} host language.
+Function composition (\cref{lst_t4t:mtasktemp:o}) and currying (\cref{lst_t4t:mtasktemp:setSds}) are inherited from the \gls{CLEAN} host language.
As \gls{MTASK} tasks are dynamically compiled, it is also possible to select and customise tasks as required at runtime.
-For example, the interval used in the \cleaninline{rpeatevery} task (\cref{lst_t4t:mtaskTemp:rpeatevery}) could be a parameter to the \cleaninline{devTask} function.
+For example, the interval used in the \cleaninline{rpeatevery} task (\cref{lst_t4t:mtasktemp:rpeatevery}) could be a parameter to the \cleaninline{devTask} function.
\newcommand{\srcmark}[1]{\marginpar[\footnotesize\emph{#1}]{\footnotesize\emph{#1}}}
\begin{lstClean}[%
numbers=left,
caption={
\Gls{CWTS}: a tierless temperature sensing \gls{IOT} system. Written in \gls{CLEAN}\slash\gls{ITASK}/\gls{MTASK}, it targets a resource-constrained sensor node. Each line is annotated with the functionality as analysed in \cref{sec_t4t:codesize}.},
- label={lst_t4t:mtaskTemp},
+ label={lst_t4t:mtasktemp},
]
module cwts
import mTask.Language, mTask.Interpret, mTask.Interpret.Device.TCP
import iTasks, iTasks.Extensions.DateTime
-deviceInfo = {TCPSettings|host="...", port=8123, pingTimeout= ?None} [+\label{lst_t4t:mtaskTemp:co0}\srcmark{CO}+]
-interval = lit 10[+\label{lst_t4t:mtaskTemp:sn0}\srcmark{SN}+]
-DHT_pin = DigitalPin D4[+\label{lst_t4t:mtaskTemp:si0}\srcmark{SI}+]
+deviceInfo = {TCPSettings | host = "...", port = 8123, pingTimeout = ?None}[+\label{lst_t4t:mtasktemp:co0}\srcmark{CO}+]
+interval = lit 10[+\label{lst_t4t:mtasktemp:sn0}\srcmark{SN}+]
+DHT_pin = DigitalPin D4[+\label{lst_t4t:mtasktemp:si0}\srcmark{SI}+]
-Start world = doTasks mainTask world[+\label{lst_t4t:mtaskTemp:wi0}\srcmark{WI}+]
+Start world = doTasks mainTask world[+\label{lst_t4t:mtasktemp:wi0}\srcmark{WI}+]
tempSDS :: SimpleSDSLens [(DateTime, Real)]
-tempSDS = sharedStore "temperatures" [][+\label{lst_t4t:mtaskTemp:di0}\srcmark{DI}+]
+tempSDS = sharedStore "temperatures" [][+\label{lst_t4t:mtasktemp:di0}\srcmark{DI}+]
latestTemp :: SDSLens () (? (DateTime, Real)) (DateTime, Real)
-latestTemp = mapReadWrite (listToMaybe, \x xs-> ?Just [x:xs]) ?None tempSDS[+\label{lst_t4t:mtaskTemp:di1}\srcmark{DI}+]
+latestTemp = mapReadWrite (listToMaybe, \x xs -> ?Just [x:xs]) ?None tempSDS[+\label{lst_t4t:mtasktemp:di1}\srcmark{DI}+]
-devTask :: Main (MTask v Real) | mtask, dht, liftsds v[+\label{lst_t4t:mtaskTemp:devTask}+]
+devTask :: Main (MTask v Real) | mtask, dht, liftsds v[+\label{lst_t4t:mtasktemp:devTask}+]
devTask =
- DHT (DHT_DHT DHT_pin DHT11) \dht ->[+\label{lst_t4t:mtaskTemp:DHT}+][+\label{lst_t4t:mtaskTemp:si1}\srcmark{SI}+]
- liftsds \localSds =[+\label{lst_t4t:mtaskTemp:liftsds}+][+\label{lst_t4t:mtaskTemp:co1}\srcmark{CO}+]
- mapRead (snd o fromJust) (dateTimeStampedShare latestTemp)[+\label{lst_t4t:mtaskTemp:o}+][+\label{lst_t4t:mtaskTemp:sn1}\srcmark{SN}+]
- In {main = rpeatEvery (ExactSec interval)[+\label{lst_t4t:mtaskTemp:rpeatevery}+][+\label{lst_t4t:mtaskTemp:sn2}\srcmark{SN}+]
- (temperature dht >>~.[+\label{lst_t4t:mtaskTemp:temperature}+][+\label{lst_t4t:mtaskTemp:si2}\srcmark{SI}+]
- setSds localSds)}[+\label{lst_t4t:mtaskTemp:setSds}+][+\label{lst_t4t:mtaskTemp:sn3}\srcmark{SN}+]
+ DHT (DHT_DHT DHT_pin DHT11) \dht ->[+\label{lst_t4t:mtasktemp:DHT}+][+\label{lst_t4t:mtasktemp:si1}\srcmark{SI}+]
+ liftsds \localSds =[+\label{lst_t4t:mtasktemp:liftsds}+][+\label{lst_t4t:mtasktemp:co1}\srcmark{CO}+]
+ mapRead (snd o fromJust) (dateTimeStampedShare latestTemp)[+\label{lst_t4t:mtasktemp:o}+][+\label{lst_t4t:mtasktemp:sn1}\srcmark{SN}+]
+ In {main = rpeatEvery (ExactSec interval)[+\label{lst_t4t:mtasktemp:rpeatevery}+][+\label{lst_t4t:mtasktemp:sn2}\srcmark{SN}+]
+ (temperature dht >>~.[+\label{lst_t4t:mtasktemp:temperature}+][+\label{lst_t4t:mtasktemp:si2}\srcmark{SI}+]
+ setSds localSds)}[+\label{lst_t4t:mtasktemp:setSds}+][+\label{lst_t4t:mtasktemp:sn3}\srcmark{SN}+]
mainTask :: Task Real
mainTask
- = withDevice deviceInfo \dev -> liftmTask} devTask dev[+\label{lst_t4t:mtaskTemp:liftmtask}+][+\label{lst_t4t:mtaskTemp:withdevice}+][+\label{lst_t4t:mtaskTemp:co2}\srcmark{CO}+]
- -|| viewSharedInformation [] latestTemp[+\label{lst_t4t:mtaskTemp:wi1}\srcmark{WI}+]
- <<@ Title "Latest temperature"[+\label{lst_t4t:mtaskTemp:wi2}\srcmark{WI}+]
+ = withDevice deviceInfo \dev -> liftmTask} devTask dev[+\label{lst_t4t:mtasktemp:liftmtask}+][+\label{lst_t4t:mtasktemp:withdevice}+][+\label{lst_t4t:mtasktemp:co2}\srcmark{CO}+]
+ -|| viewSharedInformation [] latestTemp[+\label{lst_t4t:mtasktemp:wi1}\srcmark{WI}+]
+ <<@ Title "Latest temperature"[+\label{lst_t4t:mtasktemp:wi2}\srcmark{WI}+]
\end{lstClean}
%
\label{fig_t4t:cwtsDiagram}
\end{figure}
-\section{\texorpdfstring{\gls{UOG}}{UoG} smart campus case study}%
+\section{\texorpdfstring{\glsxtrshort{UOG}}{UoG} smart campus case study}%
\label{sec_t4t:Case}
The basis for our comparison between tiered and tierless technologies are four \gls{IOT} systems that all conform to the \gls{UOG} smart campus specifications (\cref{sec_t4t:OperationalComparison}). There is a small (12 room) deployment of the conventional \gls{PYTHON}-based \gls{PRS} stack that uses Raspberry Pi supersensors, and its direct comparator is the tierless \gls{CRS} implementation: also deployed on Raspberry Pis.
To represent the more common microprocessor sensor nodes we select ESP8266X powered \gls{WEMOS} D1 Mini microcontrollers. To evaluate tierless technologies on microcontrollers we compare the conventional \gls{PYTHON}\slash\gls{MICROPYTHON} \gls{PWS} stack with the tierless \gls{CWS} implementation.
relatively powerful Raspberry Pi 3 Model Bs. There is a simple object-oriented \gls{PYTHON} collector for configuring the sensors and reading their values. The collector daemon service marshals the sensor data and transmits using \gls{MQTT} to the central monitoring server at a preset frequency.
The collector caches sensor data locally when the server is unreachable.
-In contrast to \gls{PRS}, \gls{PWS}'s sensor nodes are microprocessors running \gls{MICROPYTHON}, a dialect of \gls{PYTHON} specifically designed to run on small, low powered embedded devices~\citep{kodali2016low}.
+In contrast to \gls{PRS}, \gls{PWS}'s sensor nodes are microprocessors running \gls{MICROPYTHON}, a dialect of \gls{PYTHON} specifically designed to run on small, low powered embedded devices \citep{kodali2016low}.
To enable a fair comparison between the software stacks we are careful to use the same object-oriented software architecture, e.g.\ using the same classes in \gls{PWS} and \gls{PRS}.
-\Gls{PYTHON} and \gls{MICROPYTHON} are appropriate tiered comparison languages. Tiered \gls{IOT} systems are implemented in a whole range of programming languages, with \gls{PYTHON}, \gls{MICROPYTHON}, \gls{C} and \gls{CPP} being popular for some tiers in many implementations. \gls{C}\slash\gls{CPP} implementations would probably result in more verbose programs and even less type safety.
-The other reasons for selecting \gls{PYTHON} and \gls{MICROPYTHON} are pragmatic. \gls{PRS} had been constructed in \gls{PYTHON}, deployed, and was being used as an \gls{IOT} experimental platform.
+\Gls{PYTHON} and \gls{MICROPYTHON} are appropriate tiered comparison languages. Tiered \gls{IOT} systems are implemented in a whole range of programming languages, with \gls{PYTHON}, \gls{MICROPYTHON}, \gls{C} and \gls{CPP} being popular for some tiers in many implementations. \Gls{C}\slash\gls{CPP} implementations would probably result in more verbose programs and even less type safety.
+The other reasons for selecting \gls{PYTHON} and \gls{MICROPYTHON} are pragmatic. \Gls{PRS} had been constructed in \gls{PYTHON}, deployed, and was being used as an \gls{IOT} experimental platform.
Selecting \gls{MICROPYTHON} for the resource-constrained \gls{PWS} sensor nodes facilitates comparison by minimising changes to the resource-rich and resource-constrained codebases.
We anticipate that the codebase for a tiered smart campus implementation in another imperative/object-oriented language, like \gls{CPP}, would be broadly similar to the \gls{PRS} and \gls{PWS} codebases.
Communication between a sensor node and the server is initiated by the server.
\Gls{CRS}'s sensor nodes are Raspberry Pi 4s, and execute \gls{CLEAN}\slash\gls{ITASK} programs.
-Communication from the sensor node to the server is implicit and happens via \glspl{SDS} over \gls{TCP} using platform independent execution graph serialisation~\citep{oortgiese_distributed_2017}.
+Communication from the sensor node to the server is implicit and happens via \glspl{SDS} over \gls{TCP} using platform independent execution graph serialisation \citep{oortgiese_distributed_2017}.
\Gls{CWS}'s sensor nodes are \gls{WEMOS} microprocessors running \gls{MTASK} tasks. Communication and serialisation is, by design, very similar to \gls{ITASK}, i.e.\ via \glspl{SDS} over either a serial port connection, raw \gls{TCP}, or \gls{MQTT} over \gls{TCP}.
\end{table}
\Cref{tbl_t4t:mem} shows the maximum memory residency after garbage collection of the sensor node for all four smart campus implementations. The smart campus sensor node programs executing on the \gls{WEMOS} microprocessors have low maximum residencies: \qty{20270}{\byte} for \gls{PWS} and \qty{880}{\byte} for \gls{CWS}. In \gls{CWS} the \gls{MTASK} system generates very high level \gls{TOP} byte code that is interpreted by the \gls{MTASK} virtual machine and uses a small and predictable amount of heap memory.
-In \gls{PWS}, the hand-written \gls{MICROPYTHON} is compiled to byte code for execution on the virtual machine. Low residency is achieved with a fixed size heap and efficient memory management. For example both \gls{MICROPYTHON} and \gls{MTASK} use fixed size allocation units and mark\&sweep garbage collection to minimise memory usage at the cost of some execution time~\citep{plamauer2017evaluation}.
+In \gls{PWS}, the hand-written \gls{MICROPYTHON} is compiled to byte code for execution on the virtual machine. Low residency is achieved with a fixed size heap and efficient memory management. For example both \gls{MICROPYTHON} and \gls{MTASK} use fixed size allocation units and mark\&sweep garbage collection to minimise memory usage at the cost of some execution time \citep{plamauer2017evaluation}.
The smart campus sensor node programs executing on the Raspberry Pis have far higher maximum residencies than those executing on the microprocessors: \qty{3.5}{\mebi\byte} for \gls{PRS} and \qty{2.7}{\mebi\byte} for \gls{CRS}. In \gls{CRS} the sensor node code is a set of \gls{ITASK} executing on a full-fledged \gls{ITASK} server running in distributed child mode and this consumes far more memory.
%The memory used is actually very similar to the memory usage of the server with a single client connected.
In \gls{PRS} the sensor node program is written in \gls{PYTHON}, a language far less focused on minimising memory usage than \gls{MICROPYTHON}. For example an object like a string is larger in \gls{PYTHON} than in \gls{MICROPYTHON} and consequently does not support all features such as \emph{f-strings}.
-Furthermore, not all advanced \gls{PYTHON} feature regarding classes are available in \gls{MICROPYTHON}, i.e.\ only a subset of the \gls{PYTHON} specification is supported~\citep{diffmicro}.%\mlcomment{reference \url{https://docs.micropython.org/en/latest/genrst/index.html} ? It contains an overview of supported features}
+Furthermore, not all advanced \gls{PYTHON} feature regarding classes are available in \gls{MICROPYTHON}, i.e.\ only a subset of the \gls{PYTHON} specification is supported \citep{diffmicro}.%\mlcomment{reference \url{https://docs.micropython.org/en/latest/genrst/index.html} ? It contains an overview of supported features}
In summary the sensor node code generated by both tierless languages, \gls{ITASK} and \gls{MTASK}, is sufficiently memory efficient for the target sensor node hardware. Indeed, the maximum residencies of the \gls{CLEAN} sensor node code is less than the corresponding hand-written (Micro)\gls{PYTHON} code. Of course in a tiered stack the hand-written code can be more easily optimised to minimise residency, and this could even entail using a memory efficienthat thet language like \gls{C}\slash\gls{CPP}. However, such optimisation requires additional developer effort, and a new language would introduce additional semantic friction.
The Raspberry Pi supersensor node used in \gls{CRS} and \gls{PRS} use more power as they have a general purpose ARM processor and run mainstream Linux. With all sensors enabled, they consume \qtyrange{1}{2}{\watt}, depending on ambient load. So a microprocessor sensor node consumes an order of magnitude less power than a supersensor node.
-\section[Is tierless \texorpdfstring{\gls{IOT}}{IoT} programming easier than tiered?]{\hspace{-9pt}Is tierless \texorpdfstring{\gls{IOT}}{IoT} programming easier than tiered?}%
+\section[Is tierless \texorpdfstring{\glsxtrshort{IOT}}{IoT} programming easier than tiered?]{\hspace{-9pt}Is tierless \texorpdfstring{\glsxtrshort{IOT}}{IoT} programming easier than tiered?}%
\label{sec_t4t:ProgrammingComparison}
\label{sec_t4t:codesize}
%A comparison of the Temperature sensor in \gls{PYTHON} Micropyton, Itask \& \gls{MTASK}.
-\paragraph{Code size} is widely recognised as an approximate measure of the development and maintenance effort required for a software system~\citep{rosenberg1997some}. \gls{SLOC} is a common code size metric, and is especially useful for multi-paradigm systems like \gls{IOT} systems. It is based on the simple principle that the more \gls{SLOC}, the more developer effort and the increased likelihood of bugs~\citep{rosenberg1997some}. It is a simple measure, not dependent on some formula, and can be automatically computed~\citep{sheetz2009understanding}.
+\paragraph{Code size}
+is widely recognised as an approximate measure of the development and maintenance effort required for a software system \citep{rosenberg1997some}. \Gls{SLOC} is a common code size metric, and is especially useful for multi-paradigm systems like \gls{IOT} systems. It is based on the simple principle that the more \gls{SLOC}, the more developer effort and the increased likelihood of bugs \citep{rosenberg1997some}. It is a simple measure, not dependent on some formula, and can be automatically computed \citep{sheetz2009understanding}.
-Of course \gls{SLOC} must be used carefully as it is easily influenced by programming style, language paradigm, and counting method~\citep{alpernaswonderful}. Here we are counting code to compare development effort, use the same idiomatic programming style in each component, and only count lines of code, omitting comments and blank lines.
+Of course \gls{SLOC} must be used carefully as it is easily influenced by programming style, language paradigm, and counting method \citep{alpernaswonderful}. Here we are counting code to compare development effort, use the same idiomatic programming style in each component, and only count lines of code, omitting comments and blank lines.
\Cref{table_t4t:multi} enumerates the \gls{SLOC} required to implement the \gls{UOG} smart campus functionalities in \gls{PWS}, \gls{PRS}, \gls{CWS} and \gls{CRS}. Both \gls{PYTHON} and \gls{CLEAN} implementations use the same server and communication code for Raspberry Pi and for \gls{WEMOS} sensor nodes (rows 5--7 of the table).
The Sensor Interface (SI) refers to code facilitating the communication between the peripherals and the sensor node software. % formerly hardware interface
\begin{table}
\centering % used for centering table
- \caption{Comparing tiered and tierless smart campus code sizes: \gls{SLOC} and number of source files. \gls{PWS} and \gls{CWS} execute on resource-constrained sensor nodes, while \gls{PRS} and \gls{CRS} execute on resource-rich sensor nodes.}%
+ \caption{Comparing tiered and tierless smart campus code sizes: \gls{SLOC} and number of source files. \Gls{PWS} and \gls{CWS} execute on resource-constrained sensor nodes, while \gls{PRS} and \gls{CRS} execute on resource-rich sensor nodes.}%
\label{table_t4t:multi}
\begin{tabular}{l l c c c c } % centered columns (4 columns)
\toprule
\end{tabular}
\end{table}
-\paragraph{Code proportions.} Comparing the percentages of code required to implement the smart campus functionalities normalises the data and avoids some issues when comparing \gls{SLOC} for different programming languages, and especially for languages with different paradigms like object-oriented \gls{PYTHON} and functional \gls{CLEAN}. \Cref{fig_t4t:multipercentage} shows the percentage of the total \gls{SLOC} required to implement the smart campus functionalities in each of the four implementations, and is computed from the data in \cref{table_t4t:multi}. It shows that there are significant differences between the percentage of code for each functionality between the tiered and tierless implementations. For example 17\% of the tiered implementations specifies communication, whereas this requires only 3\% of the tierless implementations, i.e.\ 6$\times$ less. We explore the reasons for this in \cref{sec_t4t:Communication}. The other major difference is the massive percentage of Database Interface code in the tierless implementations: at least 47\%. The smart campus specification required a standard DBMS, and the \gls{CLEAN}\slash\gls{ITASK} SQL interface occupies some 78 \gls{SLOC}. While this is a little less than the 106 \gls{SLOC} used in \gls{PYTHON} (\cref{table_t4t:multi}), it is a far higher percentage of systems with total codebases of only around 160 \gls{SLOC}. Idiomatic \gls{CLEAN}/\gls{ITASK} would use high level abstractions to store persistent data in an \gls{SDS}, requiring just a few \gls{SLOC}.
+\paragraph{Code proportions.}
+Comparing the percentages of code required to implement the smart campus functionalities normalises the data and avoids some issues when comparing \gls{SLOC} for different programming languages, and especially for languages with different paradigms like object-oriented \gls{PYTHON} and functional \gls{CLEAN}. \Cref{fig_t4t:multipercentage} shows the percentage of the total \gls{SLOC} required to implement the smart campus functionalities in each of the four implementations, and is computed from the data in \cref{table_t4t:multi}. It shows that there are significant differences between the percentage of code for each functionality between the tiered and tierless implementations. For example 17\% of the tiered implementations specifies communication, whereas this requires only 3\% of the tierless implementations, i.e.\ 6$\times$ less. We explore the reasons for this in \cref{sec_t4t:Communication}. The other major difference is the massive percentage of Database Interface code in the tierless implementations: at least 47\%. The smart campus specification required a standard DBMS, and the \gls{CLEAN}\slash\gls{ITASK} SQL interface occupies some 78 \gls{SLOC}. While this is a little less than the 106 \gls{SLOC} used in \gls{PYTHON} (\cref{table_t4t:multi}), it is a far higher percentage of systems with total codebases of only around 160 \gls{SLOC}. Idiomatic \gls{CLEAN}/\gls{ITASK} would use high level abstractions to store persistent data in an \gls{SDS}, requiring just a few \gls{SLOC}.
The total size of \gls{CWS} and \gls{CRS} would be reduced by a factor of two and the percentage of Database Interface code would be even less than in the tiered \gls{PYTHON} implementations.
Before exploring the reasons for the smaller tierless codebase we compare the implementations for resource-rich and resource-constrained sensor nodes, again using \gls{SLOC} and code proportions. \Cref{table_t4t:multi} shows that the two tiered implementations are very similar in size: with \gls{PWS} for microprocessors requiring 562 \gls{SLOC} and \gls{PRS} for supersensors requiring 576 \gls{SLOC}.
The two tierless implementations are also similar in size: \gls{CWS} requiring 166 and \gls{CRS} 155 \gls{SLOC}.
-There are several main reasons for the similarity. One is that the server-side code, i.e.\ for the presentation and application layers, is identical for both resource rich/constrained implementations. The identical server code accounts for approximately 40\% of the \gls{PWS} and \gls{PRS} codebases, and approximately 85\% of the \gls{CWS} and \gls{CRS} codebases (\cref{fig_t4t:multipercentage}). For the perception and network layers on the sensor nodes, the \gls{PYTHON} and \gls{MICROPYTHON} implementations have the same structure, e.g.\ a class for each type of sensor, and use analogous libraries. Indeed, approaches like CircuitPython~\citep{CircuitPython} allow the same code to execute on both resource-rich and resource-constrained sensor nodes.
+There are several main reasons for the similarity. One is that the server-side code, i.e.\ for the presentation and application layers, is identical for both resource rich/constrained implementations. The identical server code accounts for approximately 40\% of the \gls{PWS} and \gls{PRS} codebases, and approximately 85\% of the \gls{CWS} and \gls{CRS} codebases (\cref{fig_t4t:multipercentage}). For the perception and network layers on the sensor nodes, the \gls{PYTHON} and \gls{MICROPYTHON} implementations have the same structure, e.g.\ a class for each type of sensor, and use analogous libraries. Indeed, approaches like CircuitPython \citep{CircuitPython} allow the same code to execute on both resource-rich and resource-constrained sensor nodes.
-Like \gls{PYTHON} and \gls{MICROPYTHON}, \gls{ITASK} and \gls{MTASK} are designed to be similar, as elaborated in \cref{sec_t4t:ComparingTierless}. The similarity is apparent when comparing the \gls{ITASK} \gls{CRTS} and \gls{ITASK}\slash\gls{MTASK} \gls{CWTS} room temperature systems in \cref{lst_t4t:itaskTempFull,lst_t4t:mtaskTemp}. That is, both implementations use similar \glspl{SDS} and lenses; they have similar \cleaninline{devTask}s that execute on the sensor node, and the server-side \cleaninline{mainTask}s are almost identical: they deploy the remote \cleaninline{devTask} before generating the web page to report the readings.
+Like \gls{PYTHON} and \gls{MICROPYTHON}, \gls{ITASK} and \gls{MTASK} are designed to be similar, as elaborated in \cref{sec_t4t:ComparingTierless}. The similarity is apparent when comparing the \gls{ITASK} \gls{CRTS} and \gls{ITASK}\slash\gls{MTASK} \gls{CWTS} room temperature systems in \cref{lst_t4t:itaskTempFull,lst_t4t:mtasktemp}. That is, both implementations use similar \glspl{SDS} and lenses; they have similar \cleaninline{devTask}s that execute on the sensor node, and the server-side \cleaninline{mainTask}s are almost identical: they deploy the remote \cleaninline{devTask} before generating the web page to report the readings.
In both \gls{PYTHON} and \gls{CLEAN} the resource-constrained implementations are less than 7\% larger than the resource-rich implementations. This suggests that \emph{the development and maintenance effort of simple \gls{IOT} systems for resource-constrained and for resource-rich sensor nodes is similar in tierless technologies,} just as it is in tiered technologies.
A caveat is that the smart campus system is relatively simple, and developing more complex perception and network code on bare metal may prove more challenging. That is, the lack of \gls{OS} support, and the restricted languages and libraries, may have greater impact. We return to this issue in \cref{sec_t4t:ComparingTierless}.
The vast majority of \gls{IOT} systems are implemented using a number of different programming languages and paradigms, and these must be effectively used and interoperated. A major reason that the tierless \gls{IOT} implementations are simpler and shorter than the tiered implementations is that they use far fewer programming languages and paradigms. Here we use language to distinguish \glspl{EDSL} from their host language: so \gls{ITASK} and \gls{MTASK} are considered distinct from \gls{CLEAN}; and to distinguish dialects: so \gls{MICROPYTHON} is considered distinct from \gls{PYTHON}.
-The tierless implementations use just two conceptually-similar \glspl{DSL} embedded in the same host language, and a single paradigm (\cref{table_t4t:languages,table_t4t:paradigms}). In contrast, the tiers in \gls{PRS} and \gls{PWS} use six or more very different languages, and both imperative and declarative paradigms. Multiple languages are commonly used in other typical software systems like web stacks, e.g.\ a recent survey of open source projects reveals that on average at least five different languages are used~\citep{mayer2015empirical}. Interoperating components in multiple languages and paradigms raises a plethora of issues.
+The tierless implementations use just two conceptually-similar \glspl{DSL} embedded in the same host language, and a single paradigm (\cref{table_t4t:languages,table_t4t:paradigms}). In contrast, the tiers in \gls{PRS} and \gls{PWS} use six or more very different languages, and both imperative and declarative paradigms. Multiple languages are commonly used in other typical software systems like web stacks, e.g.\ a recent survey of open source projects reveals that on average at least five different languages are used \citep{mayer2015empirical}. Interoperating components in multiple languages and paradigms raises a plethora of issues.
-Interoperation \emph{increases the cognitive load on the developer} who must simultaneously think in multiple languages and paradigms. This is commonly known as semantic friction or impedance mismatch~\citep{ireland2009classification}. A simple illustration of this is that the tiered \gls{PRS} source code comprises some 38 source and configuration files, whereas the tierless \gls{CRS} requires just 3 files (\cref{table_t4t:multi}). The source could be structured as a single file, but to separate concerns is structured into three modules, one each for \glspl{SDS}, types, and control logic~\citep{wang_maintaining_2018}.
+Interoperation \emph{increases the cognitive load on the developer} who must simultaneously think in multiple languages and paradigms. This is commonly known as semantic friction or impedance mismatch \citep{ireland2009classification}. A simple illustration of this is that the tiered \gls{PRS} source code comprises some 38 source and configuration files, whereas the tierless \gls{CRS} requires just 3 files (\cref{table_t4t:multi}). The source could be structured as a single file, but to separate concerns is structured into three modules, one each for \glspl{SDS}, types, and control logic \citep{wang_maintaining_2018}.
The developer must \emph{correctly interoperate the components}, e.g.\ adhere to the \gls{API} or communication protocols between components. The interoperation often entails additional programming tasks like marshalling or demarshalling data between components. For example, in the tiered \gls{PRS} and \gls{PWS} architectures, \gls{JSON} is used to serialise and deserialise data strings from the \gls{PYTHON} collector component before storing the data in the Redis database (\cref{lst_t4t:json}).
%e.g.\ to marshall and demarshall data between components.
\subsection{Automatic communication}%
\label{sec_t4t:Communication}
-In conventional tiered \gls{IOT} implementations the developer must write and maintain code to communicate between tiers. For example \gls{PRS} and \gls{PWS} create, send and read \gls{MQTT}~\citep{light2017mosquitto} messages
+In conventional tiered \gls{IOT} implementations the developer must write and maintain code to communicate between tiers. For example \gls{PRS} and \gls{PWS} create, send and read \gls{MQTT} \citep{light2017mosquitto} messages
between the perception and application layers. \Cref{table_t4t:multi} shows that communication between these layers require some 94 \gls{SLOC} in \gls{PWS} and 98 in \gls{PRS}, accounting for 17\% of the codebase (bottom bars in \cref{fig_t4t:multipercentage}). To illustrate, \cref{lst_t4t:mwssmqtt} shows part of the code to communicate sensor readings from the \gls{PWS} sensor node to the Redis store on the server.
Not only must the tiered developer write additional code, but \gls{IOT} communication code is often intricate. In such a distributed system the sender and receiver must be correctly configured, correctly follow the communication protocol through all execution states, and deal with potential failures. For example line 3 of \cref{lst_t4t:mwssmqtt}: \pythoninline{redis host = config.get('Redis', 'Host')} will fail if either the host or IP are incorrect.
In contrast, the tierless \gls{CWS} and \gls{CRS} communication is not only highly automated, but also automatically correct because matching sender and receiver code is generated by the compiler. \Cref{table_t4t:multi} shows that communication is specified in just 5 \gls{SLOC} in \gls{CWS} and 4 in \gls{CRS}, or just 3\% of the codebase (bottom bars in \cref{fig_t4t:multipercentage}).
-\Cref{lst_t4t:mtaskTemp} illustrates communication in a tierless \gls{IOT} language. That is, the \gls{CWTS} temperature sensor requires just three lines of communication code, and uses just three communication functions. The
-\cleaninline{withDevice} function on \cref{lst_t4t:mtaskTemp:withdevice} integrates a sensor node with the server, allowing tasks to be sent to it. The
-\cleaninline{liftmTask} on \cref{lst_t4t:mtaskTemp:liftmtask} integrates an \gls{MTASK} in the \gls{ITASK} runtime by compiling it and sending it for interpretation to the sensor node.
-The \cleaninline{liftsds} on \cref{lst_t4t:mtaskTemp:liftsds} integrates \glspl{SDS} from \gls{ITASK} into \gls{MTASK}, allowing \gls{MTASK} tasks to interact with data from the \gls{ITASK} server.
+\Cref{lst_t4t:mtasktemp} illustrates communication in a tierless \gls{IOT} language. That is, the \gls{CWTS} temperature sensor requires just three lines of communication code, and uses just three communication functions. The
+\cleaninline{withDevice} function on \cref{lst_t4t:mtasktemp:withdevice} integrates a sensor node with the server, allowing tasks to be sent to it. The
+\cleaninline{liftmTask} on \cref{lst_t4t:mtasktemp:liftmtask} integrates an \gls{MTASK} in the \gls{ITASK} runtime by compiling it and sending it for interpretation to the sensor node.
+The \cleaninline{liftsds} on \cref{lst_t4t:mtasktemp:liftsds} integrates \glspl{SDS} from \gls{ITASK} into \gls{MTASK}, allowing \gls{MTASK} tasks to interact with data from the \gls{ITASK} server.
The exchange of data, user interface, and communication are all automatically generated.
\subsection{High level abstractions}%
\label{sec_t4t:abstractions}
Another reason that the tierless \gls{CLEAN} implementations are concise is because they use powerful higher order \gls{IOT} programming abstractions.
-For comprehensibility the simple temperature sensor from \cref{sec_t4t:mtasks} (\cref{lst_t4t:mtaskTemp}) is used to compare the expressive power of \gls{CLEAN} and \gls{PYTHON}-based \gls{IOT} programming abstractions.
+For comprehensibility the simple temperature sensor from \cref{sec_t4t:mtasks} (\cref{lst_t4t:mtasktemp}) is used to compare the expressive power of \gls{CLEAN} and \gls{PYTHON}-based \gls{IOT} programming abstractions.
There are implementations for all four configurations: \gls{PRTS} (\gls{PYTHON} Raspberry Pi Temperature Sensor)\footnotemark, \gls{PWTS}\footnotemark[\value{footnote}]
\footnotetext{Lubbers, M.; Koopman, P.; Ramsingh, A.; Singer, J.; Trinder, P. (2021): Source code, line counts and memory stats for PRS, PWS, PRT and PWT.\ Zenodo.\ \href{https://doi.org/10.5281/zenodo.5081386}{10.5281/zenodo.5081386}.}, \gls{CRTS}\footnotemark{} and \gls{CWTS}\footnotemark[\value{footnote}].
\footnotetext{Lubbers, M.; Koopman, P.; Ramsingh, A.; Singer, J.; Trinder, P. (2021): Source code, line counts and memory stats for CRS, CWS, CRTS and CWTS.\ Zenodo.\ \href{https://doi.org/10.5281/zenodo.5040754}{10.5281/zenodo.5040754}.}
\label{table_t4t:temp}
\begin{tabular}{llccl}
\toprule
- Location & Functionality & \gls{PWTS} & \gls{CWTS} & Lines (\cref{lst_t4t:mtaskTemp})\\
+ Location & Functionality & \gls{PWTS} & \gls{CWTS} & Lines (\cref{lst_t4t:mtasktemp})\\
\midrule
- Sensor Node & Sensor Interface & 14 & 3 & \labelcref{lst_t4t:mtaskTemp:si0,lst_t4t:mtaskTemp:si1,lst_t4t:mtaskTemp:si2}\\
- & Sensor Node & 67 & 4 & \labelcref{lst_t4t:mtaskTemp:sn0,lst_t4t:mtaskTemp:sn1,lst_t4t:mtaskTemp:sn2,lst_t4t:mtaskTemp:sn3}\\
- Server & Web Interface & 17 & 3 & \labelcref{lst_t4t:mtaskTemp:wi0,lst_t4t:mtaskTemp:wi1,lst_t4t:mtaskTemp:wi2}\\
- & Database Interface & 106 & 2 & \labelcref{lst_t4t:mtaskTemp:di0,lst_t4t:mtaskTemp:di1}\\
- Communication & Communication & 94 & 3 & \labelcref{lst_t4t:mtaskTemp:co0,lst_t4t:mtaskTemp:co1,lst_t4t:mtaskTemp:co2}\\
+ Sensor Node & Sensor Interface & 14 & 3 & \labelcref{lst_t4t:mtasktemp:si0,lst_t4t:mtasktemp:si1,lst_t4t:mtasktemp:si2}\\
+ & Sensor Node & 67 & 4 & \labelcref{lst_t4t:mtasktemp:sn0,lst_t4t:mtasktemp:sn1,lst_t4t:mtasktemp:sn2,lst_t4t:mtasktemp:sn3}\\
+ Server & Web Interface & 17 & 3 & \labelcref{lst_t4t:mtasktemp:wi0,lst_t4t:mtasktemp:wi1,lst_t4t:mtasktemp:wi2}\\
+ & Database Interface & 106 & 2 & \labelcref{lst_t4t:mtasktemp:di0,lst_t4t:mtasktemp:di1}\\
+ Communication & Communication & 94 & 3 & \labelcref{lst_t4t:mtasktemp:co0,lst_t4t:mtasktemp:co1,lst_t4t:mtasktemp:co2}\\
\midrule
% \multicolumn{2}{c}{Total (\textnumero{} Files)} & 298 (27) & 15 (1) \\
Total \gls{SLOC} & & 298 & 15 \\
Firstly, \gls{FP} languages are generally more concise than most other programming languages because their powerful abstractions like higher-order and/or polymorphic functions require less code to describe a computation.
Secondly, the \gls{TOP} paradigm used in \gls{ITASK} and \gls{MTASK} reduces the code size further by making it easy to specify \gls{IOT} functionality concisely.
As examples, the step combinator \cleaninline{>>*.} allows the task value on the left-hand side to be observed until one of the steps is enabled;
-and the \cleaninline{viewSharedInformation} (line 31 of \cref{lst_t4t:mtaskTemp}) part of the UI will be automatically updated when the value of the \gls{SDS} changes. Moreover, each \gls{SDS} provides automatic updates to all coupled \glspl{SDS} and associated tasks. Thirdly, the amount of explicit type information is minimised in comparison to other languages, as much is automatically inferred~\citep{hughes1989functional}.
+and the \cleaninline{viewSharedInformation} (line 31 of \cref{lst_t4t:mtasktemp}) part of the UI will be automatically updated when the value of the \gls{SDS} changes. Moreover, each \gls{SDS} provides automatic updates to all coupled \glspl{SDS} and associated tasks. Thirdly, the amount of explicit type information is minimised in comparison to other languages, as much is automatically inferred \citep{hughes1989functional}.
-\section{Could tierless \texorpdfstring{\gls{IOT}}{IoT} programming be more reliable than tiered?}%
+\section{Could tierless \texorpdfstring{\glsxtrshort{IOT}}{IoT} programming be more reliable than tiered?}%
\label{sec_t4t:Discussion}
\subsection{Type safety}%
\label{sec_t4t:typesafety}
Strong typing identifies errors early in the development cycle, and hence plays a crucial role in improving software quality. In consequence almost all modern languages provide strong typing, and encourage static typing to minimise runtime errors.
-% Phil: so widely known that a citation is unnecessary~\citep{madsen1990strong}.
-That said, many distributed system components written in languages that primarily use static typing, like \gls{HASKELL} and Scala, use some dynamic typing, e.g.\ to ensure that the data arriving in a message has the anticipated type~\citep{epstein2011towards,gupta2012akka}.
+% Phil: so widely known that a citation is unnecessary \citep{madsen1990strong}.
+That said, many distributed system components written in languages that primarily use static typing, like \gls{HASKELL} and Scala, use some dynamic typing, e.g.\ to ensure that the data arriving in a message has the anticipated type \citep{epstein2011towards,gupta2012akka}.
In a typical tiered multi-language \gls{IOT} system the developer must integrate software in different languages with very different type systems, and potentially executing on different hardware. The challenges of maintaining type safety have long been recognised as a major component of the semantic friction in multi-language systems, e.g.\ \citep{ireland2009classification}.
-Even if the different languages used in two components are both strongly typed, they may attribute, often quite subtly, different types to a value. Such type errors can lead to runtime errors, or the application silently reporting erroneous data. Such errors can be hard to find. Automatic detection of such errors is sometimes possible, but requires an addition tool like Jinn~\citep{Jinn,Furr2005}.
+Even if the different languages used in two components are both strongly typed, they may attribute, often quite subtly, different types to a value. Such type errors can lead to runtime errors, or the application silently reporting erroneous data. Such errors can be hard to find. Automatic detection of such errors is sometimes possible, but requires an addition tool like Jinn \citep{Jinn,Furr2005}.
%Such errors can be hard to debug, partly because there is very limited tool support for detecting them
-%Phil: another possible source to discuss ~\citep{egyed1999automatically}
+%Phil: another possible source to discuss \citep{egyed1999automatically}
\begin{lstPython}[caption={\Gls{PRS} loses type safety as a sensor node sends a {\tt\footnotesize double}, and the server stores a {\tt\footnotesize string}.},label={lst_t4t:float},morekeywords={message,enum,uint64,double}]
message SensorData {
Analysis of the \gls{PRS} codebase reveals an instance where it, fairly innocuously, loses type safety. The fragment in \cref{lst_t4t:float} first shows a \pythoninline{double} sensor value being sent from the sensor node, and then shows the value being stored in Redis as a \pythoninline{string} on the server. As \gls{PWS} preserves the same server components it also suffers from the same loss of type safety.
-\emph{A tierless language makes it possible to guarantee type safety across an entire \gls{IOT} stack}. For example the \gls{CLEAN} compiler guarantees static type safety as the entire \gls{CWS} software stack is type checked, and generated, from a single source. Tierless web stack languages like Links~\citep{cooper2006links} and Hop~\citep{serrano2006hop} provide the same guarantee for web stacks.
+\emph{A tierless language makes it possible to guarantee type safety across an entire \gls{IOT} stack}. For example the \gls{CLEAN} compiler guarantees static type safety as the entire \gls{CWS} software stack is type checked, and generated, from a single source. Tierless web stack languages like Links \citep{cooper2006links} and Hop \citep{serrano2006hop} provide the same guarantee for web stacks.
\subsection{Failure management}%
\begin{lstClean}[caption={An \gls{MTASK} failover combinator.},label={lst_t4t:failover}]
failover :: [TCPSettings] (Main (MTask BCInterpret a)) -> Task a
failover [] _ = throw "Exhausted device pool"
-failover [d:ds] mtask = try ( withDevice d (liftmTask mtask) ) except
+failover [d:ds] mtask = try (withDevice d (liftmTask mtask)) except
where except MTEUnexpectedDisconnect = failover ds mtask
except _ = throw e
\end{lstClean}
\subsection{Support}%
\label{sec_t4t:support}
%\mlcomment{I've shortened this quite a bit}
-Community and tool support are essential for engineering reliable production software. \gls{PRS} and \gls{PWS} are both \gls{PYTHON} based, and \gls{PYTHON}\slash\gls{MICROPYTHON} are among the most popular programming languages~\citep{cass2020top}. \gls{PYTHON} is also a common choice for some tiers of \gls{IOT} applications~\citep{tanganelli2015coapthon}.
+Community and tool support are essential for engineering reliable production software. \Gls{PRS} and \gls{PWS} are both \gls{PYTHON} based, and \gls{PYTHON}\slash\gls{MICROPYTHON} are among the most popular programming languages \citep{cass2020top}. \Gls{PYTHON} is also a common choice for some tiers of \gls{IOT} applications \citep{tanganelli2015coapthon}.
Hence, there are a wide range of development tools like \glspl{IDE} and debuggers, a thriving community and a wealth of training material. There are even specialised \gls{IOT} Boards like PyBoard \& WiPy that are specifically programmed using \gls{PYTHON} variations like \gls{MICROPYTHON}.
In contrast, tierless languages are far less mature than the languages used in tiered stacks, and far less widely adopted.
Acquiring information about the systems requires distilling academic papers and referring to the source code.
There is a \gls{CLEAN} \gls{IDE}, but it does not contain support for the \gls{ITASK} or \gls{MTASK} \glspl{DSL}.
-\section{Comparing tierless languages for resource-rich/constrained sensor nodes}%
+\section[Comparing tierless languages for resource-rich\slash{}constrained sensor nodes]%
+ {\hspace{-1.7499pt}Comparing tierless languages for resource-rich\slash{}constrained sensor nodes}%
\label{sec_t4t:ComparingTierless}
This section compares two tierless \gls{IOT} languages: one for resource-rich, and the other for resource-constrained, sensor nodes. Key issues are the extent to which the very significant resource constraints of a microprocessor limit the language, and the benefits of executing on bare metal, i.e.\ without an \gls{OS}.
\subsection{Language restrictions for resource-constrained execution}
-Executing components on a resource-constrained sensor node imposes restrictions on programming abstractions available in a tierless \gls{IOT} language or \gls{DSL}. The small and fixed-size memory are key limitations. The limitations are shared by any high-level language that targets microprocessors such as BIT, PICBIT, PICOBIT, Microscheme and uLisp~\citep{dube_bit:_2000,feeley_picbit:_2003,st-amour_picobit:_2009,suchocki_microscheme:_2015, johnson-davies_lisp_2020}.
+Executing components on a resource-constrained sensor node imposes restrictions on programming abstractions available in a tierless \gls{IOT} language or \gls{DSL}. The small and fixed-size memory are key limitations. The limitations are shared by any high-level language that targets microprocessors such as BIT, PICBIT, PICOBIT, Microscheme and uLisp \citep{dube_bit:_2000,feeley_picbit:_2003,st-amour_picobit:_2009,suchocki_microscheme:_2015, johnson-davies_lisp_2020}.
Even in low level languages some language features are disabled by default when targeting microprocessors, such as runtime type information (RTTI) in \gls{CPP}.
Here we investigate the restrictions imposed by resource-constrained sensor nodes on \gls{MTASK}, in comparison with \gls{ITASK}. While \gls{ITASK} and \gls{MTASK} are by design superficially similar languages, to execute on resource-constrained sensor nodes \gls{MTASK} tasks are more restricted, and have a different semantics.
Programmers can, however, use any construct of the \gls{CLEAN} host language to construct an \gls{MTASK} program, including higher order functions and arbitrary data types. For example folding an \gls{MTASK} combinator over a list of tasks.
The only restriction is that any higher order function must be macro expanded to a first order \gls{MTASK} program before being compiled to byte code.
%\mlcomment{Pieter: Refine paragraph about macro expansion and currying/HOF}
-As an example in \cref{lst_t4t:mtaskTemp} we use \cleaninline{temperature dht >>~.} \cleaninline{setSds localSds} instead of \cleaninline{temperature dht >>~.} \cleaninline{\\temp -> setSds localSds temp}.
+As an example in \cref{lst_t4t:mtasktemp} we use \cleaninline{temperature dht >>~.} \cleaninline{setSds localSds} instead of \cleaninline{temperature dht >>~.} \cleaninline{\\temp -> setSds localSds temp}.
%However, this is limited to situations where the expressions are expanded to the required \gls{MTASK} types, i.e.\ the host language acts as a macro language for \gls{MTASK}.
%\mlcomment{I've refined this. The host language does not offer limited use of HOF and currying. It only appears to offer, just macro expansion}.
%\pwtcomment{I've rewritten: please check.}
\subsection{The benefits of a bare metal execution environment}
Despite the language restrictions, components of a tierless language executing on a microprocessor can exploit the bare metal environment. Many of these benefits are shared by other bare metal languages like \gls{MICROPYTHON} or \gls{C}\slash\gls{CPP}. So as \gls{MTASK} executes on bare metal it has some advantages over \gls{ITASK}. Most notably \gls{MTASK} has better control of timing as on bare metal there are no other processes or threads that compete for CPU cycles.
-This makes the \gls{MTASK} \cleaninline{repeatEvery} (\cref{lst_t4t:mtaskTemp}, \cref{lst_t4t:mtaskTemp:sn2}) much more accurate than the \gls{ITASK} \cleaninline{waitForTimer} (\cref{lst_t4t:itaskTempFull}, \cref{lst_t4t:itaskTempFull:waitForTimer}).
+This makes the \gls{MTASK} \cleaninline{repeatEvery} (\cref{lst_t4t:mtasktemp}, \cref{lst_t4t:mtasktemp:sn2}) much more accurate than the \gls{ITASK} \cleaninline{waitForTimer} (\cref{lst_t4t:itaskTempFull}, \cref{lst_t4t:itaskTempFull:waitForTimer}).
While exact timing is not important in this example, it is significant for many other \gls{IOT} applications.
In contrast \gls{ITASK} cannot give real time guarantees. One reason is that an \gls{ITASK} server can ship an arbitrary number of \gls{ITASK} or \gls{MTASK} tasks to a device.
Such competing tasks, or indeed other \gls{OS} threads and processes, consume processor time and reduce the accuracy of timings.
However, even when using multiple \gls{MTASK} tasks, it is easier to control the number of tasks on a device than controlling the number of processes and threads executing under an \gls{OS}.
An \gls{MTASK} program has more control over energy consumption.
-The \gls{MTASK} \gls{EDSL} and the \gls{MTASK} \gls{RTS} are designed to minimise energy usage~\citep{crooijmans_reducing_2021}.
+The \gls{MTASK} \gls{EDSL} and the \gls{MTASK} \gls{RTS} are designed to minimise energy usage \citep{crooijmans_reducing_2021}.
Intensional analysis of the declarative task description and current progress at run time allow the \gls{RTS} to schedule tasks and maximise idle time.
As the \gls{RTS} is the only program running on the device, it can enforce deep sleep and wake up without having to worry about influencing other processes.
\subsection{Summary}
\Cref{table_t4t:languagecomparison} summarises the differences between the \gls{CLEAN} \gls{IOT} \gls{EDSL} and their host language.
-The restrictions imposed by a resource-constrained execution environment on the tierless \gls{IOT} language are relatively minor. Moreover the \gls{MTASK} programming abstraction is broadly compatible with \gls{ITASK}. As a simple example compare the \gls{ITASK} and \gls{MTASK} temperature sensors in \cref{lst_t4t:itaskTempFull,lst_t4t:mtaskTemp}. As a more realistic example, the \gls{MTASK} based \gls{CWS} smart campus implementation is similar to the \gls{ITASK} based \gls{CRS}, and requires less than 10\% additional code: 166 \gls{SLOC} compared with 155 \gls{SLOC} (\cref{table_t4t:multi}).
+The restrictions imposed by a resource-constrained execution environment on the tierless \gls{IOT} language are relatively minor. Moreover the \gls{MTASK} programming abstraction is broadly compatible with \gls{ITASK}. As a simple example compare the \gls{ITASK} and \gls{MTASK} temperature sensors in \cref{lst_t4t:itaskTempFull,lst_t4t:mtasktemp}. As a more realistic example, the \gls{MTASK} based \gls{CWS} smart campus implementation is similar to the \gls{ITASK} based \gls{CRS}, and requires less than 10\% additional code: 166 \gls{SLOC} compared with 155 \gls{SLOC} (\cref{table_t4t:multi}).
-Even with these restrictions, \gls{MTASK} programming is at a far higher level of abstraction than almost all bare metal languages, e.g.\ BIT, PICBIT, PICOBIT and Microscheme. That is \gls{MTASK} provides a set of higher order task combinators, shared distributed data stores, \etc. (\cref{sec_t4t:mtasks}). Moreover, it seems that common sensor node programs are readily expressed using \gls{MTASK}. In addition to the \gls{CWTS} and \gls{CWS} systems outlined here, other case studies include Arduino examples as well as some bigger tasks~\citep{koopman_task-based_2018,lubbers_writing_2019,LubbersMIPRO}. We conclude that the programming of sensor tasks is well-supported by both \glspl{DSL}.
+Even with these restrictions, \gls{MTASK} programming is at a far higher level of abstraction than almost all bare metal languages, e.g.\ BIT, PICBIT, PICOBIT and Microscheme. That is \gls{MTASK} provides a set of higher order task combinators, shared distributed data stores, \etc. (\cref{sec_t4t:mtasks}). Moreover, it seems that common sensor node programs are readily expressed using \gls{MTASK}. In addition to the \gls{CWTS} and \gls{CWS} systems outlined here, other case studies include Arduino examples as well as some bigger tasks \citep{koopman_task-based_2018,lubbers_writing_2019,LubbersMIPRO}. We conclude that the programming of sensor tasks is well-supported by both \glspl{DSL}.
\section{Conclusion}%
\label{sec_t4t:Conclusion}
We show that \emph{tierless languages have the potential to significantly reduce the development effort for \gls{IOT} systems}. Specifically the tierless \gls{CWS} and \gls{CRS} stacks require far less code, i.e.\ 70\% fewer \gls{SLOC}, than the tiered \gls{PWS} and \gls{PRS} stacks (\cref{table_t4t:multi}). We analyse the code reduction and attribute it to the following three main factors.
\begin{enumerate*}
\item Tierless developers need to manage less interoperation: \gls{CRS} uses a single \gls{DSL} and paradigm, and \gls{CWS} uses two \glspl{DSL} in a single paradigm and three source code files. In contrast, both \gls{PRS} and \gls{PWS} use at least six languages in two paradigms and spread over at least 35 source code files (\cref{table_t4t:multi,table_t4t:languages,table_t4t:paradigms}). Thus, a tierless stack minimises semantic friction.
- \item Tierless developers benefit from automatically generated, and hence correct, communication (\cref{lst_t4t:mtaskTemp}), and write 6$\times$ less communication code (\cref{fig_t4t:multipercentage}).
+ \item Tierless developers benefit from automatically generated, and hence correct, communication (\cref{lst_t4t:mtasktemp}), and write 6$\times$ less communication code (\cref{fig_t4t:multipercentage}).
\item Tierless developers can exploit powerful high-level declarative and task-oriented \gls{IOT} programming abstractions (\cref{table_t4t:temp}), specifically the composable, higher-order task combinators outlined in \cref{sec_t4t:itasks}.
-Our empirical results for \gls{IOT} systems are consistent with the benefits claimed for tierless languages in other application domains. Namely that a tierless language provides a \textit{Higher Abstraction Level}, \textit{Improved Software Design}, and improved \textit{Program Comprehension}~\citep{weisenburger2020survey}.
+Our empirical results for \gls{IOT} systems are consistent with the benefits claimed for tierless languages in other application domains. Namely that a tierless language provides a \textit{Higher Abstraction Level}, \textit{Improved Software Design}, and improved \textit{Program Comprehension} \citep{weisenburger2020survey}.
\end{enumerate*}
We show that \emph{tierless languages have the potential to significantly improve the reliability of \gls{IOT} systems}. We illustrate how \gls{CLEAN} maintains type safety, contrasting this with a loss of type safety in \gls{PRS}.
-We illustrate higher order failure management in \gls{CLEAN}\slash\gls{ITASK}/\gls{MTASK} in contrast to the \gls{PYTHON}-based failure management in \gls{PRS}. For maintainability a tiered approach makes replacing components easy, but refactoring within the components is far harder than in a tierless \gls{IOT} language. Again our findings are consistent with the simplied \textit{Code Maintenance} benefits claimed for tierless languages~\citep{weisenburger2020survey}.
+We illustrate higher order failure management in \gls{CLEAN}\slash\gls{ITASK}/\gls{MTASK} in contrast to the \gls{PYTHON}-based failure management in \gls{PRS}. For maintainability a tiered approach makes replacing components easy, but refactoring within the components is far harder than in a tierless \gls{IOT} language. Again our findings are consistent with the simplied \textit{Code Maintenance} benefits claimed for tierless languages \citep{weisenburger2020survey}.
Finally, we contrast community support for the technologies (\cref{sec_t4t:Discussion}).
-%\pwtcomment{Pieter: please check discussion of ~\citep{weisenburger2020survey} in preceding 2 paragraphs}
+%\pwtcomment{Pieter: please check discussion of \citep{weisenburger2020survey} in preceding 2 paragraphs}
We report \emph{the first comparison of a tierless \gls{IOT} codebase for resource-rich sensor nodes with one for resource-constrained sensor nodes}.
\begin{enumerate*}
\end{enumerate*}
We present \emph{the first comparison of two tierless \gls{IOT} languages: one designed for resource-constrained sensor nodes (\gls{CLEAN} with \gls{ITASK} and \gls{MTASK}), and the other for resource-rich sensor nodes (\gls{CLEAN} with \gls{ITASK}).} \gls{CLEAN}\slash\gls{ITASK} can implement all layers of the \gls{IOT} stack if the sensor nodes have the computational resources, as the Raspberry Pis do in \gls{CRS}. On resource constrained sensor nodes \gls{MTASK} are required to implement the perception and network layers, as on the \gls{WEMOS} minis in \gls{CWS}. We show that a bare metal execution environment allows \gls{MTASK} to have better control of peripherals, timing and energy consumption. The memory available on a microprocessor restricts the programming abstractions available in \gls{MTASK} to a fixed set of combinators, no user defined or recursive data types, strict evaluation, and makes it harder to add new abstractions. Even with these restrictions \gls{MTASK} provide a higher level of abstraction than most bare metal languages, and can readily express many \gls{IOT} applications including the \gls{CWS} \gls{UOG} smart campus application (\cref{sec_t4t:ComparingTierless}).
-Our empirical results are consistent with the benefits of tierless languages listed in Section 2.1 of~\citep{weisenburger2020survey}.
+Our empirical results are consistent with the benefits of tierless languages listed in Section 2.1 of \citep{weisenburger2020survey}.
\subsection{Reflections}
This study is based on a specific pair of tierless \gls{IOT} languages, and the \gls{CLEAN} language frameworks represent a specific set of tierless language design decisions. Many alternative tierless \gls{IOT} language designs are possible, and some are outlined in \cref{sec_t4t:characteristics}. Crucially the limitations of the tierless \gls{CLEAN} languages, e.g.\ that they currently provide limited security, should not be seen as limitations of tierless technologies in general.
-This study has explored some, but not all, of the potential benefits of tierless languages for \gls{IOT} systems. An \gls{IOT} system specified as a single tierless program is amenable to a host of programming language technologies. For example, if the language has a formal semantics, as Links, Hop and \gls{CLEAN} tasks do~\citep{cooper2006links,serrano2006hop,plasmeijer_task-oriented_2012}, it is possible to prove properties of the system, e.g.\ \citep{Steenvoorden2019tophat}. As another example program analyses can be applied, and \cref{sec_t4t:characteristics} and~\citep{weisenburger2020survey} outline some of the analyses could be, and in some cases have been, used to improve \gls{IOT} systems. Examples include automatic tier splitting~\citep{10.1145/2661136.2661146}, and controlling information flow to enhance security~\citep{valliappan_towards_2020}.
+This study has explored some, but not all, of the potential benefits of tierless languages for \gls{IOT} systems. An \gls{IOT} system specified as a single tierless program is amenable to a host of programming language technologies. For example, if the language has a formal semantics, as Links, Hop and \gls{CLEAN} tasks do \citep{cooper2006links,serrano2006hop,plasmeijer_task-oriented_2012}, it is possible to prove properties of the system, e.g.\ \citep{Steenvoorden2019tophat}. As another example program analyses can be applied, and \cref{sec_t4t:characteristics} and \citep{weisenburger2020survey} outline some of the analyses could be, and in some cases have been, used to improve \gls{IOT} systems. Examples include automatic tier splitting \citep{10.1145/2661136.2661146}, and controlling information flow to enhance security \citep{valliappan_towards_2020}.
While offering real benefits for \gls{IOT} systems development, tierless languages also raise some challenges. Programmers must master new tierless programming abstractions, and the semantics of these automatic multi-tier behaviours are necessarily relatively complex. In the \gls{CLEAN} context this entails becoming proficient with the \gls{ITASK} and \gls{MTASK} \glspl{DSL}. Moreover, specifying a behaviour that is not already provided by the tierless language requires either a workaround, or extending a \gls{DSL}. However, implementing the relatively simple smart campus application required no such adaption. Finally, tierless \gls{IOT} technology is very new, and both tool and community support have yet to mature.