From 7d63dca7576e612310ef746a800996e204828ab4 Mon Sep 17 00:00:00 2001 From: Mart Lubbers Date: Wed, 1 Feb 2023 20:21:03 +0100 Subject: [PATCH] many small changes --- appx/c4hp.tex | 58 +++++++++++++--------------- back/samenvatting.tex | 3 +- glossaries.tex | 2 +- intro/intro.tex | 2 +- other.bib | 6 +-- process_bib.sh | 1 + top/4iot.tex | 89 ++++++++++++++++++++++--------------------- 7 files changed, 79 insertions(+), 82 deletions(-) diff --git a/appx/c4hp.tex b/appx/c4hp.tex index 5b8e099..2108c81 100644 --- a/appx/c4hp.tex +++ b/appx/c4hp.tex @@ -8,27 +8,24 @@ \chapter{\texorpdfstring{\glsentrytext{CLEAN}}{Clean} for \texorpdfstring{\glsentrytext{HASKELL}}{Haskell} Programmers}% \label{chp:clean_for_haskell_programmers} -This appendix is meant to give people who are familiar with the \gls{FP} language \gls{HASKELL} a consise overview of the \gls{CLEAN} language elements and how they differ from \gls{HASKELL}. +This appendix is meant give people who are familiar with the \gls{FP} language \gls{HASKELL} a consise overview of the programming language \gls{CLEAN} and how it differs from \gls{HASKELL}. The goal is to support the reader when reading \gls{CLEAN} code. \Cref{tbl:syn_clean_haskell} shows frequently occuring \gls{CLEAN} language elements on the left side and their \gls{HASKELL} equivalent on the right side. Obviously, this summary is not exhaustive. Some \gls{CLEAN} language elements that are not easily translatable to \gls{HASKELL} and thus do not occur in the summary following below. We hope you enjoy these notes and that it aids you in reading \gls{CLEAN} programs. -While \gls{CLEAN} and \gls{HASKELL} were both conceived around 1987 and have similar syntax, there are some subtle differences in syntax and functionality. -This section describes some of the history of \gls{CLEAN} and provides a crash course in \gls{CLEAN} pecularities written for \gls{HASKELL} programmers. -It is based on the - \Gls{CLEAN}---acronym for Clean \glsxtrlong{LEAN} \citep{barendregt_towards_1987}---, was originally designed as a \gls{GRS} core language but quickly served as an intermediate language for other functional languages \citep{brus_clean_1987}. -In the early days it has also been called \emph{Concurrent} \gls{CLEAN} \citep{nocker_concurrent_1991} but these days the language has no support for this anymore. -Fast forward thirty years, \gls{CLEAN} is now a robust language with state-of-the-art features and is actually used in industry as well as academia---albeit in select areas of the world \citep{plasmeijer_clean_2021}. +In the early days it has also been called \emph{Concurrent} \gls{CLEAN} \citep{nocker_concurrent_1991} but these days the language has no support for concurrency anymore. +Fast-forward thirty years, \gls{CLEAN} is now a robust language with state-of-the-art features and is actually used in industry as well as academia---albeit in select areas of the world. Initially, when it was used mostly as an intermediate language, it had a fairly spartan syntax. However, over the years, the syntax got friendlier and it currently it looks a lot like \gls{HASKELL}. -In the past, a \emph{double-edged} fronted even existed that allowed \gls{CLEAN} to be extended with \gls{HASKELL98} syntax and vice versa, however this frontend is no longer maintained \citep{van_groningen_exchanging_2010}. -This chapter therefore gives a brief syntactical and functional comparison, a complete specification of the \gls{CLEAN} language can be found in the latest language report \citep{plasmeijer_clean_2021}. -Many of this is based on work by Achten although that was based on \gls{CLEAN} 2.1 and \gls{HASKELL98} \citep{achten_clean_2007}. -When \gls{HASKELL} is mentioned we actually mean \gls{GHC}'s \gls{HASKELL}\footnote{If an extension is enabled, a footnote is added stating that \GHCmod{SomeExtension} is required.} this is denoted and by \gls{CLEAN} we mean \gls{CLEAN} 3.1's compiler with the \gls{ITASK} extensions. +In the past, a \emph{double-edged} fronted even existed that allowed \gls{CLEAN} to be extended with \gls{HASKELL98} syntax and vice versa \citep{van_groningen_exchanging_2010}, however this frontend is no longer maintained. +This chapter gives only a brief syntactical and functional comparison. +A complete specification of the \gls{CLEAN} language can be found in the latest language report \citep{plasmeijer_clean_2021}. +Much of this is based on work by Achten, although that was based on \gls{CLEAN} 2.1 and \gls{HASKELL98} \citep{achten_clean_2007}. +When \gls{HASKELL} is mentioned we actually mean \gls{GHC}'s \gls{HASKELL}\footnote{If an extension is enabled, a footnote is added stating that \GHCmod{SomeExtension} is required.} and by \gls{CLEAN} we mean \gls{CLEAN} 3.1's compiler with the \gls{ITASK} extensions. \section{Features} \subsection{Modules} @@ -42,20 +39,20 @@ Choosing what is exported in \gls{HASKELL} is done using the \haskellinline{modu \subsection{Strictness} In \gls{CLEAN}, by default, all expressions are evaluated lazily. Types can be annotated with a strictness attributes (\cleaninline{!}), resulting in the values being evaluated to head-normal form before the function is entered. -In \gls{HASKELL}, in patterns, strictness can be enforced using \haskellinline{!}\requiresGHCmod{BangPatterns}. -Within functions the strict let (\cleaninline{#!}) can be used to force evaluate an expression, in \gls{HASKELL} \haskellinline{seq} or \haskellinline{\$!} is used for this. +In \gls{HASKELL}, in patterns, strictness is enforced using \haskellinline{!}\requiresGHCmod{BangPatterns}. +Within functions, the strict let (\cleaninline{#!}) is used to force evaluate an expression, in \gls{HASKELL} \haskellinline{seq} or \haskellinline{\$!} is used for this. \subsection{Uniqueness typing} -Types in \gls{CLEAN} may be \emph{unique}, which means that they may not be shared \citep{barendsen_uniqueness_1996}. +Types in \gls{CLEAN} may be \emph{unique}, which means that they cannot be shared \citep{barendsen_uniqueness_1996}. The uniqueness type system allows the compiler to generate efficient code because unique data structures can be destructively updated. Furthermore, uniqueness typing serves as a model for side effects as well \citep{achten_high_1993,achten_ins_1995}. \Gls{CLEAN} uses the \emph{world-as-value} paradigm where \cleaninline{World} represents the external environment and is always unique \citep{backus_introduction_1990}. A program with side effects is characterised by a \cleaninline{Start :: *World -> *World} start function. In \gls{HASKELL}, interaction with the world is done using the \haskellinline{IO} monad \citep{peyton_jones_imperative_1993}. -The \haskellinline{IO} monad could very well be---and actually is---implemented in \gls{CLEAN} using a state monad with the \cleaninline{World} as a state. +An \haskellinline{IO} monad could very well be---and actually is---implemented in \gls{CLEAN} using a state monad with the \cleaninline{World} as a state. Besides marking types as unique, it is also possible to mark them with uniqueness attributes variables \cleaninline{u:} and define constraints on them. For example, to make sure that an argument of a function is at least as unique as another argument. -Finally, using \cleaninline{.} (a dot), it is possible to state that several variables are equally unique. +Finally, using \cleaninline{.} (a full stop), it is possible to state that several variables are equally unique. Uniqueness is propagated automatically in function types but must be marked manually in data types. Examples can be seen in \cref{lst:unique_examples}. @@ -70,7 +67,7 @@ f :: v:a u:b -> u:b, [v<=u] // f works when a is less unique than b \subsection{Expressions} Patterns in \gls{CLEAN} can be used as predicates as well \citep[\citesection{3.4.3}]{plasmeijer_clean_2021}. -Using the \cleaninline{=:} operator, a value can be tested against a pattern. +Using the \cleaninline{=:} operator, a value is tested against a pattern. Variable names are not allowed but wildcard patterns \cleaninline{\_} are. \begin{lstClean}[label={lst:matches_pattern_expression},caption={Examples of \emph{matches pattern} expressions.}] @@ -98,22 +95,22 @@ readChars file \subsection{Generics} Polytypic functions \citep{jeuring_polytypic_1996}---also known as generic or kind-indexed fuctions---are built into \gls{CLEAN} \citep[\citesection{7.1}]{plasmeijer_clean_2021}\citep{alimarine_generic_2005} whereas in \gls{HASKELL} they are implemented as a library \citep[\citesection{6.19.1}]{ghc_team_ghc_2021}. -The implementation of generics in \gls{CLEAN} is very similar to that of Generic H$\forall$skell \citep{hinze_generic_2003}. +The syntax of the built-in generics of \gls{CLEAN} is very similar to that of Generic H$\forall$skell \citep{hinze_generic_2003}. %When calling a generic function, the kind must always be specified and depending on the kind, the function may require more arguments. For example, defining a generic equality is done as in \cref{lst:generic_eq}. -\cleaninputlisting[firstline=4,label={lst:generic_eq},caption={Generic equality function in \gls{CLEAN}.}.]{lst/generic_eq.icl} +\cleaninputlisting[firstline=4,label={lst:generic_eq},caption={Generic equality function}]{lst/generic_eq.icl} -Metadata about the types is available using the \cleaninline{of} syntax that gives the function access to metadata records, as can be seen in \cref{lst:generic_print} showing a generic print function. This abundance of metadata allows for very complex generic functions that near the expression level of template metaprogramming\ifSubfilesClassLoaded{}{ (See \cref{chp:first-class_datatypes})}. -\cleaninputlisting[language=Clean,firstline=4,label={lst:generic_print},caption={Generic print function in \gls{CLEAN}.}]{lst/generic_print.icl} +Metadata about the types is available using the \cleaninline{of} syntax that gives the function access to metadata records, as can be seen in \cref{lst:generic_print} showing a generic print function. This abundance of metadata allows for very complex generic functions that near the expression level of template metaprogramming (see \cref{chp:first-class_datatypes,sec:ccodegen}). +\cleaninputlisting[language=Clean,firstline=4,label={lst:generic_print},caption={Generic print function}]{lst/generic_print.icl} \subsection{\texorpdfstring{\glsentrytext{GADT}}{GADT}s} \Glspl{GADT} are enriched data types that allow the type instantiation of the constructor to be explicitly defined \citep{cheney_first-class_2003,hinze_fun_2003}. While \glspl{GADT} are not natively supported in \gls{CLEAN}, they can be simulated using embedding-projection pairs or equivalence types \citep[\citesection{2.2}]{cheney_lightweight_2002}. -To illustrate this, \cref{lst:gadt_clean} shows an example \gls{GADT} that would be implemented in \gls{HASKELL} as done in \cref{lst:gadt_haskell}\requiresGHCmod{GADTs}. +To illustrate this, \cref{lst:gadt_haskell} shows a \gls{GADT} in \gls{HASKELL}\requiresGHCmod{GADTs} that can be implemented as in \cref{lst:gadt_clean}. -\cleaninputlisting[firstline=4,lastline=24,label={lst:gadt_clean},caption={Expression \gls{GADT} using equivalence types.}]{lst/expr_gadt.icl} \haskellinputlisting[firstline=4,label={lst:gadt_haskell},caption={Expression \gls{GADT}.}]{lst/expr_gadt.hs} +\cleaninputlisting[firstline=4,lastline=24,label={lst:gadt_clean},caption={Expression \gls{GADT} using equivalence types.}]{lst/expr_gadt.icl} \clearpage \section{Syntax} @@ -142,8 +139,6 @@ To illustrate this, \cref{lst:gadt_clean} shows an example \gls{GADT} that would \midrule \cleaninline{import Mod => qualified f1, :: t} & \haskellinline{import qualified Mod (f1, t)}\\ & \haskellinline{import Mod hiding (f1, t)}\\ - \cleaninline{/* multi line /* nested */ */} & \haskellinline{\{- multi line \{- nested -\} \}}\\ - \midrule \multicolumn{2}{c}{Basic types}\\ \midrule @@ -151,8 +146,8 @@ To illustrate this, \cref{lst:gadt_clean} shows an example \gls{GADT} that would \cleaninline{True :: Bool} & \haskellinline{True :: Bool}\\ \cleaninline{toInteger 42 :: Integer} & \haskellinline{42 :: Integer}\\ \cleaninline{38.0 :: Real} & \haskellinline{38.0 :: Float -- or Double}\\ - \cleaninline{\"Hello\" +++ \"World\" :: String}\footnote{Strings are represented as unboxed character arrays.} - & \haskellinline{\"Hello\" ++ \"World\" :: String}\footnote{Strings are represented as lists of characters by default but may be overloaded as well if \GHCmod{OverloadedStrings} is enabled.}\\ + \cleaninline{\"Hello\" +++ \"World\" :: String}\footnote{Strings are unboxed character arrays.} + & \haskellinline{\"Hello\" ++ \"World\" :: String}\footnote{Strings are lists of characters by default but may be overloaded as well if \GHCmod{OverloadedStrings} is enabled.}\\ \cleaninline{['Hello'] :: [Char]} & \haskellinline{\"Hello\" :: String}\\ \cleaninline{?t} & \haskellinline{Maybe t}\\ \cleaninline{(?None, ?Just e)} & \haskellinline{(Nothing, Just e)}\\ @@ -161,7 +156,7 @@ To illustrate this, \cref{lst:gadt_clean} shows an example \gls{GADT} that would \multicolumn{2}{c}{Type definitions}\\ \midrule \cleaninline{:: T a0 ... :== t} & \haskellinline{type T a0 ... = t}\\ - \cleaninline{:: T a0 ... } & \haskellinline{data T a1 ...}\\ + \cleaninline{:: T a0 ... } & \haskellinline{data T a0 ...}\\ \quad\cleaninline{= C1 f0 ... fn \| ... \| Cn f0 ... fn} & \quad\haskellinline{= C1 f0 ... fn \| ... \| Cn f0 ... fn}\\ \cleaninline{:: T a0 ...} & \haskellinline{data T a0 ...}\\ \quad\cleaninline{= \{ f0 :: t0, ..., fn :: tn \} } & \quad\haskellinline{= T \{ f0 :: t0, ..., fn :: tn \} }\\ @@ -222,6 +217,7 @@ To illustrate this, \cref{lst:gadt_clean} shows an example \gls{GADT} that would \quad\cleaninline{\| otherwise = t} or \cleaninline{= t} & \quad\haskellinline{\| otherwise = t}\\ \midrule + \pagebreak \multicolumn{2}{c}{Record expressions}\\ \midrule \cleaninline{:: R = \{ f :: t \}} & \haskellinline{data R = R \{ f :: t \}}\\ @@ -234,8 +230,8 @@ To illustrate this, \cref{lst:gadt_clean} shows an example \gls{GADT} that would \midrule \multicolumn{2}{c}{Record patterns}\\ \midrule - \cleaninline{:: R0 = \{ f0 :: R1 \}} & \haskellinline{data R0 = R0 \{ f0 :: R1 \}}\\ - \cleaninline{:: R1 = \{ f1 :: t \}} & \haskellinline{data R1 = R1 \{ f1 :: t \}}\\ + \cleaninline{:: R0 = \{ f0 :: R1 Int \}} & \haskellinline{data R0 = R0 \{ f0 :: R1 Int \}}\\ + \cleaninline{:: R1 t = \{ f1 :: t \}} & \haskellinline{data R1 t = R1 \{ f1 :: t \}}\\ \cleaninline{g \{ f0 \} = e f0} & \haskellinline{g (R0 \{f0=x\}) = e x}\\ & or \haskellinline{g (R0 \{f0\}) = e f0}\requiresGHCmod{RecordPuns}\\ \cleaninline{g \{ f0 = \{f1\} \} = e f1} & \haskellinline{g (R0 \{f0=R1 \{f1=x\}\}) = e x}\\ @@ -247,7 +243,7 @@ To illustrate this, \cref{lst:gadt_clean} shows an example \gls{GADT} that would \cleaninline{a = \{v0, ..., vn\}} & \haskellinline{a = array (0, n+1)}\\ & \quad\haskellinline{[(0, v0), ..., (n, vn)]}\\ \cleaninline{a = \{e \\\\ p <-: a\}} & \haskellinline{a = array (0, length a-1)}\\ - & \quad\haskellinline{[e \| (i, a) <- [0..] `zip` a]}\\ + & \quad\haskellinline{[e \| (i, a) <- zip [0..] a]}\\ \cleaninline{a.[i]} & \haskellinline{a!i}\\ \cleaninline{a![i]}\footnote{This operator allows for field selection from unique arrays.} & \haskellinline{(\\v->(v!i, v)) a}\\ \cleaninline{\{ a \& [i] = e\}} & \haskellinline{a//[(i, e)]}\\ diff --git a/back/samenvatting.tex b/back/samenvatting.tex index edb15e9..721913a 100644 --- a/back/samenvatting.tex +++ b/back/samenvatting.tex @@ -8,8 +8,7 @@ \ifSubfilesClassLoaded{\chapter*{Samenvatting}}{\chapter{Samenvatting}}% \label{chp:samenvatting} %\begin{center} -\noindent% -\todo{lang\-uage de\-pen\-dent ac\-ro\-nyms?} +%\noindent% Dit is een samenvatting van 350--400 woorden. %\end{center} diff --git a/glossaries.tex b/glossaries.tex index edae456..f3733b9 100644 --- a/glossaries.tex +++ b/glossaries.tex @@ -34,7 +34,7 @@ \myacronym{IR}{IR}{intermediate representation} \myacronym{ISR}{ISR}{interrupt service routine} \myacronym{LEAN}{LEAN}{language of East-Anglia and Nijmegen} -\myacronym[prefixfirst={a\ },prefix={an\ }]{LED}{LED}{light-emitting diode} +\myacronym[category=noexpand,prefixfirst={a\ },prefix={an\ }]{LED}{LED}{light-emitting diode} \myacronym{OLED}{OLED}{organic \glsxtrlong{LED}} \myacronym[category=noexpand]{OS}{OS}{operating system} \myacronym{OTA}{OTA}{over-the-air} diff --git a/intro/intro.tex b/intro/intro.tex index 01475cf..6880f89 100644 --- a/intro/intro.tex +++ b/intro/intro.tex @@ -17,7 +17,7 @@ \end{itemize} \end{chapterabstract} -There are at least 13.4 billion devices connected to the internet at the time of writing \citep{transformation_insights_current_2023}. +There are at least 13.4 billion devices connected to the internet at the time of writing \citep{transforma_insights_current_2023}. Each of these sense, act, or otherwise, interacts with people, computers, and the environment. Despite their immense diversity in characteristics, they are all computers and they they all require software to operate. diff --git a/other.bib b/other.bib index 168a87e..ddf712d 100644 --- a/other.bib +++ b/other.bib @@ -134,7 +134,7 @@ language = {English}, urldate = {2021-02-24}, publisher = {Release}, - author = {GHC Team}, + author = {{GHC Team}}, year = {2021}, file = {GHC Team - 2021 - GHC User’s Guide Documentation.pdf:/home/mrl/.local/share/zotero/storage/87ZT5VXL/GHC Team - 2021 - GHC User’s Guide Documentation.pdf:application/pdf}, } @@ -145,7 +145,7 @@ language = {English}, urldate = {2021-02-24}, publisher = {Release}, - author = {GHC Team}, + author = {{GHC Team}}, year = {2021}, } @@ -617,7 +617,7 @@ few changes in existing programs.}, isbn = {978-90-386-3462-3}, abstract = {In this article I argue that it is important to develop experiential prototypes which have multi-tasking capabilities. At the same time I show that for embedded prototype software based on the popular Arduino platform this is not too difficult. The approach is explained and illustrated using technical examples – practical and hands-on, down to the code level. At the same time a few helpful notations for designing and documenting the software are introduced and illustrated by the same examples. Finally a few case studies of the technical approach are listed.}, language = {English}, - booktitle = {Design and semantics of form and movement. 8th {International} {Conference} on {Design} and {Semantics} of {Form} and {Movement} ({DeSForM} 2013)}, + booktitle = {8th {International} {Conference} on {Design} and {Semantics} of {Form} and {Movement} ({DeSForM} 2013)}, author = {Feijs, Loe}, editor = {Chen, L. L. and Djajadiningrat, T. and Feijs, L. M. G. and Fraser, S. and Hu, J. and Kyffin, S. and Steffen, D.}, year = {2013}, diff --git a/process_bib.sh b/process_bib.sh index e1bdb49..73ba41f 100755 --- a/process_bib.sh +++ b/process_bib.sh @@ -7,5 +7,6 @@ fi sed -i \ -e '/url = {https\?:\/\/\(doi.org\|link\.springer\|ieeexplore\|dl\.acm\|services\.igi-global\|arxiv\.org\)/d'\ -e 's/{Transforma Insights}/{&}/g'\ + -e 's/{GHC Team}/{&}/g'\ -e 's/λ/$\\lambda$/g'\ "${@}" diff --git a/top/4iot.tex b/top/4iot.tex index bea4eb0..2af8bf8 100644 --- a/top/4iot.tex +++ b/top/4iot.tex @@ -14,23 +14,23 @@ \item introducing edge device programming; \item showing how to create the \emph{Hello World!} application for microcontrollers using \gls{ARDUINO} and \gls{MTASK}; \item extending the idea to cooperative multitasking, uncovering problems using \gls{ARDUINO}; - \item demonstrating that upgrading to a multi-tasking variant is straightforward using \gls{MTASK}; + \item demonstrating that upgrading to a multitasking variant is straightforward using \gls{MTASK}; \item elaborating on integrating an edge device program with a server; - \item and providing a reading guide for the rest of the monograph. + \item and providing a reading guide for the remainder of the monograph. \end{itemize} \end{chapterabstract} The edge layer of \gls{IOT} systems predominantly consists of microcontrollers. -Microcontrollers are tiny computers designed specifically for embedded applications that differ much from regular computers in all aspects. +Microcontrollers are tiny computers designed specifically for embedded applications that differ much from regular computers. They are much smaller; only have a fraction of the memory and processor speed; and run on different architectures. However, they have much more energy-efficient sleep modes, and support connecting and interfacing with peripherals such as sensors and actuators. -\Cref{tbl:mcu_laptop} compares the hardware properties of a typical laptop with two very popular microcontrollers. +To illustrate the difference in characteristics, \cref{tbl:mcu_laptop} compares the hardware properties of a typical laptop with two popular microcontrollers. Usually, programming microcontrollers requires an elaborate multi-step toolchain of compilation, linkage, binary image creation, and burning this image onto the flash memory of the microcontroller in order to run a program. -The programs are usually cyclic executives instead of tasks running in an \gls{OS}, i.e.\ there is only a single all-encompassing task that continuously runs on the bare metal. +The software is usually a cyclic executive instead of tasks that run in an \gls{OS}. Hence, all tasks must be manually combined into a single program. \begin{table} - \caption{Hardware characteristics of typical microcontrollers and a laptop.}% + \caption{Hardware characteristics of a laptop and two typical microcontrollers.}% \label{tbl:mcu_laptop} \centering \begin{tabular}{llll} @@ -49,32 +49,34 @@ Hence, all tasks must be manually combined into a single program. \end{tabular} \end{table} -Different models of microcontrollers require their own vendor-provided drivers, hardware abstraction layer, compilers and \glspl{RTS}. -To structure this jungle of tools, platforms exist that provide abstraction layers over the low-level toolchains such as \gls{ARDUINO}\footnote{\refurl{https://www.arduino.cc}{\formatdate{19}{12}{2022}}}. +All models of microcontrollers require their own vendor-provided drivers, hardware abstraction layer, compilers and \glspl{RTS}. +To structure this jungle of tools, platforms exist that provide abstraction layers over the low-level toolchains. +An example of this is \gls{ARDUINO}\footnote{\refurl{https://www.arduino.cc}{\formatdate{19}{12}{2022}}}. It is specifically designed for education and prototyping and hence used here to illustrate traditional microcontroller programming. The popular \gls{ARDUINO} \ccpp{} dialect and accompanying libraries provide an abstraction layer for common microcontroller behaviour allowing the programmer to program multiple types of microcontrollers using a single language. Originally it was designed for the in-house developed open-source hardware with the same name but the setup allows porting to many architectures by vendor-provided \emph{cores}. -It provides an \gls{IDE} and toolchain automation to perform all steps of the toolchain with a single command. +It provides an \gls{IDE} and toolchain automation to easily run code with a single press of a button. \section{\texorpdfstring{\Glsxtrshort{TOP} for the \glsxtrshort{IOT}}{TOP for the IoT}} \Gls{TOP} is a programming paradigm that allows multi-tier interactive systems to be generated from a single declarative source (see \cref{sec:back_top}). An example of a \gls{TOP} system is \gls{ITASK}, a general-purpose \gls{TOP} language for programming interactive distributed web applications. -Interactive distributed web applications often form the core of the top two layers of \gls{IOT} applications. -Furthermore, \gls{IOT} edge devices are typically programmed with similar workflow-like programs for which \gls{TOP} is very suitable. -Directly incorporating the perception layer in \gls{ITASK} however is not straightforward. -\Gls{ITASK} targets relatively fast and hence energy-hungry systems with large amounts of \gls{RAM} and a speedy connection. +Such web applications often form the core of the top two layers of an \gls{IOT} application. +\Gls{IOT} edge devices are typically programmed with similar workflow-like programs for which \gls{TOP} is very suitable. +Directly incorporating the perception layer, and thus edge devices, in \gls{ITASK} however is not straightforward. +The \gls{ITASK} system is targetting relatively fast and hence energy-hungry systems with large amounts of \gls{RAM} and a speedy connection. Edge devices in \gls{IOT} systems are typically slow but energy efficient and do not have the memory to run the naturally heap-heavy feature-packed functional programs that \gls{ITASK} programs are. -The \gls{MTASK} system bridges this gap by providing a \gls{TOP} \gls{DSL} for \gls{IOT} edge devices. -Domain-specific knowledge is embedded in the language and execution platform; and unnecessary features for edge devices are removed to drastically lowere the hardware requirements.\todo{beter?} +The \gls{MTASK} system bridges this gap by providing a domain-specific \gls{TOP} language for \gls{IOT} edge devices. +Domain-specific knowledge is embedded in the language and execution platform; and unnecessary features for edge devices are removed to drastically lowere the hardware requirements. \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. +This program has the single task of printing the text \emph{Hello World!} to the screen and exiting again. +It helps the programmer to become familiarised with the syntax of the language and to verify that the toolchain and runtime environment are working. Microcontrollers usually do not come with screens in the traditional sense. Nevertheless, almost always there is a built-in 1 pixel screen with a \qty{1}{\bit} color depth, namely the on-board \gls{LED}. The \emph{Hello World!} equivalent on microcontrollers blinks this \gls{LED}. -Using \gls{ARDUINO}'s \ccpp{} dialect to create the blink program results in the code seen in \cref{lst:arduinoBlink}. +Using \gls{ARDUINO}'s \ccpp{} dialect to create the blink program, results in the code seen in \cref{lst:arduinoBlink}. \Gls{ARDUINO} programs are implemented as cyclic executives and hence, each program defines a \arduinoinline{setup} and a \arduinoinline{loop} function. The \arduinoinline{setup} function is executed only once on boot, the \arduinoinline{loop} function is continuously called afterwards and contains the event loop. In the blink example, the \arduinoinline{setup} function only contains code for setting the \gls{GPIO} pin to the correct mode. @@ -85,7 +87,6 @@ In between, it waits \qty{500}{\ms} so that the blinking is actually visible for void setup() { pinMode(D2, OUTPUT); } - void loop() { digitalWrite(D2, HIGH); delay(500); @@ -95,13 +96,15 @@ void loop() { \subsection{Blinking the \texorpdfstring{\glsxtrshort{LED}}{LED} in \texorpdfstring{\gls{MTASK}}{mTask}.} Naively translating the traditional blink program to \gls{MTASK} can be done by simply substituting some syntax as seen in \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. +E.g.\ \arduinoinline{digitalWrite} becomes \cleaninline{writeD}, literals are prefixed with \cleaninline{lit}, and \arduinoinline{pinMode} becomes \arduinoinline{declarePin}. In contrast to the imperative \gls{CPP} dialect, \gls{MTASK} is a \gls{TOP} language and therefore there is no such thing as a loop, only task combinators to combine tasks. -To simulate a loop, the \cleaninline{rpeat} task combinator can be used as this task combinator executes the argument task and, when stable, reinstates it. -The body of the \cleaninline{rpeat} contains similarly named tasks to write to the pins and to wait in between. +The task is not the single cyclic executive and therefore consists of just a main expression. +The task resulting from the main expression is continuously executed by the \gls{RTS}. +To simulate a loop, the \cleaninline{rpeat} task combinator is used as this task combinator executes the argument task and, when stable, reinstates it. +The body of the \cleaninline{rpeat} task contanis a task that writes to the pins and waits in between. The tasks are connected using the sequential \cleaninline{>>|.} combinator that for all current intents and purposes executes the tasks after each other. -\begin{lstClean}[caption={Blinking the \gls{LED} using the \cleaninline{rpeat} combinator.},label={lst:blinkImp}] +\begin{lstClean}[float=ht,caption={Blinking the \gls{LED} using the \cleaninline{rpeat} combinator.},label={lst:blinkImp}] blinkTask :: Main (MTask v ()) | mtask v blinkTask = declarePin D2 PMOutput \ledPin-> {main = rpeat ( @@ -112,11 +115,12 @@ blinkTask = declarePin D2 PMOutput \ledPin-> } \end{lstClean} -However, as \gls{MTASK} is hosted in a full fledged functional language, it is also possible to define the blinking behaviour as a function. +The \gls{MTASK} \gls{DSL} is hosted in a full fledged \gls{FP} language. +It is therefore also possible to define the blinking behaviour as a function. \Cref{lst:blinkFun} shows this more natural translation. The \cleaninline{main} expression is just a call to the \cleaninline{blink} function parametrised with the state. -The \cleaninline{blink} function first writes the current state to the \gls{LED}, waits for the specific time and calls itself recursively with the inverse of the state, resulting in the same behaviour. -Creating recursive functions like this is not possible in the \gls{ARDUINO} language because the program would run out of stack quickly and combining multiple tasks defined this would be very difficult. +The \cleaninline{blink} function first writes the current state to the \gls{LED}, waits for the specific time and calls itself recursively with the inverse of the state, resulting in the blinking behaviour. +Creating recursive functions like this is not possible in the \gls{ARDUINO} language because the program would run out of stack quickly and combining multiple tasks defined like this would be very difficult. \begin{lstClean}[caption={Blinking the \gls{LED} using a function.},label={lst:blinkFun}] blinkTask :: Main (MTask v ()) | mtask v @@ -128,21 +132,19 @@ blinkTask = declarePin D2 PMOutput \ledPin-> In {main = blink true} \end{lstClean} -\section{Multi tasking} +\section{Multitasking} Now say that we want to blink multiple blinking patterns on different \glspl{LED} concurrently. For example, blink three \glspl{LED} connected to \gls{GPIO} pins $1,2$ and $3$ at intervals of \qtylist{500;300;800}{\ms}. -Intuitively you would want to lift the blinking behaviour to a function and call this function three times with different parameters as shown in \cref{lst:blinkthreadno}. +Intuitively you would want to lift the blinking behaviour to a function in order to minimise duplicate code and increase modularity and call this function three times with different parameters as shown in \cref{lst:blinkthreadno}. -\begin{lstArduino}[caption={Naive approach to multiple blinking patterns.},label={lst:blinkthreadno}] +\begin{lstArduino}[float=ht,caption={Naive approach to multiple blinking patterns.},label={lst:blinkthreadno}] void setup () { ... } - -void blink (int pin, int wait) { +void blink(int pin, int wait) { digitalWrite(pin, HIGH); delay(wait); digitalWrite(pin, LOW); delay(wait); } - void loop() { blink (D1, 500); blink (D2, 300); @@ -151,15 +153,16 @@ void loop() { Unfortunately, this does not work because the \arduinoinline{delay} function blocks all further execution. The resulting program blinks 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 and interleave it manually \citep{feijs_multi-tasking_2013}. \Cref{lst:blinkthread} shows how three different blinking patterns could be implemented in \gls{ARDUINO} using the slicing method. If we want the blink function to be a separate parametrisable function we need to explicitly provide all references to the required global state. Furthermore, the \arduinoinline{delay} function can not be used and polling \arduinoinline{millis} is required. -The \arduinoinline{millis} function returns the number of milliseconds that have passed since the boot of the microcontroller. +The \arduinoinline{millis} function returns the number of \unit{\ms} that have passed since the boot of the microcontroller. If the delay is long enough, it may also be possible to put the processor in sleep mode, reducing the power consumption drastically. -Hence, using \arduinoinline{millis} potentially affects power consumption since the processor is basically busy looping all the time. -Manually combining tasks into a single program is very error prone, requires a lot of pointer juggling, and generally results into spaghetti code. -Furthermore, it is very difficult to represent dependencies between threads, often state machines have to be explicitly programmed by hand to achieve this. +Hence, using \arduinoinline{millis} potentially affects power consumption since the processor is busy looping all the time. +Manually combining tasks into a single modular program is very error prone, requires a lot of pointer juggling, and generally results into spaghetti code. +Furthermore, it is very difficult to represent dependencies between threads. +Often state machines have to be explicitly programmed and merged by hand to achieve this. In the simple case of blinking three \glspl{LED} according to fixed intervals, it is possible to calculate the delays in advance using static analysis and generate the appropriate \arduinoinline{delay} calls. Unfortunately, this is very hard when for example the blinking patterns are determined at runtime. @@ -168,24 +171,22 @@ long led1 = 0, led2 = 0, led3 = 0; bool st1 = false, st2 = false, st3 = false; void setup () { ... } - void blink(int pin, int interval, long *lastrun, bool *st) { if (millis() - *lastrun > interval) { digitalWrite(pin, *st = !*st); *lastrun += interval; } } - void loop() { blink(D1, 500, &led1, &st1); blink(D2, 300, &led2, &st1); blink(D3, 800, &led3, &st1); }\end{lstArduino} -\subsection{Multi tasking in \texorpdfstring{\gls{MTASK}}{mTask}} +\subsection{Multitasking in \texorpdfstring{\gls{MTASK}}{mTask}} In contrast to the \arduinoinline{delay} function in \gls{ARDUINO}, \gls{MTASK}'s \cleaninline{delay} \emph{task} does not block the execution. It has no observable value until the target waiting time has passed, and thence is \emph{stable}. -To make code reuse possible and make the implementation more intuitive, the blinking behaviour is lifted to a recursive function instead of using the imperatively looking \cleaninline{rpeat} task combinator. +To make code reuse possible and make the implementation more intuitive, the blinking behaviour is lifted to a recursive function as well instead of using the imperatively looking \cleaninline{rpeat} task combinator. There is no global state, the function is parametrized with the current status, the pin to blink and the waiting time. With a parallel combinator, tasks are executed in an interleaved fashion. Therefore, blinking three different blinking patterns is as simple as combining the three calls to the \cleaninline{blink} function with their arguments as seen in \cref{lst:blinkthreadmtask}. @@ -211,17 +212,17 @@ blinktask = declarePin D1 PMOutput \d1-> The edge layer of \gls{IOT} systems is powered by microcontrollers. Microcontrollers have significantly different characteristics to regular computers. Programming them happens through compiled firmwares using low-level imperative programming languages. -Due to the lack of an \gls{OS}, writing applications that perform multiple tasks at the same time is error prone, and complex; and requires a lot of boilerplate and manual scheduling code. +Due to the lack of an \gls{OS}, writing applications that perform multiple tasks at the same time is error prone, becomes complex, requires a lot of boilerplate, and needs manual scheduling code. With the \gls{MTASK} system, a \gls{TOP} programming language for \gls{IOT} edge devices, this limitation can be overcome. -As much domain-specific knowledge is built into the language and the \gls{RTS}, the hardware requirements can be kept relatively low while maintaining a high abstraction level. +Since much domain-specific knowledge is built into the language and \gls{RTS}, the hardware requirements can be kept relatively low while maintaining a high abstraction level. Furthermore, the programs are automatically integrated with \gls{ITASK}, allowing for data sharing, task coordination, and dynamic construction of tasks. The following chapters thoroughly introduce all aspects of the \gls{MTASK} system. First the language setup and interface is shown in \cref{chp:mtask_dsl}. Then, \cref{chp:implementation} provides the implementation of the \gls{DSL}, the compilation schemes, instruction set and details on the interpreter. \Cref{chp:integration_with_itask} shows the integration of \gls{MTASK} and \gls{ITASK}. -\Cref{chp:green_computing_mtask} explains all the green computing aspects of \gls{MTASK}, i.e.\ task scheduling and processor interrupts. -Finally, \cref{chp:finale} concludes, and shows related work together with a short history of \gls{MTASK}. +\Cref{chp:green_computing_mtask} explains all green computing aspects of \gls{MTASK}, i.e.\ task scheduling and processor interrupts. +Finally, \cref{chp:finale} concludes and shows related work together with a short history of \gls{MTASK}. \input{subfilepostamble} \end{document} -- 2.20.1