--- /dev/null
+The communication from the server to the client and vice versa is just a
+character stream containing encoded \gls{mTask} messages. The \CI{synFun}
+belonging to the device is responsible for sending the content in the left
+channel and putting received messages in the right channel. Moreover, the
+boolean value should be set to \CI{True} when the connection is terminated. The
+specific encoding of the messages is visible in
+Appendix~\ref{app:communication-protocol}. The type holding the messages is
+shown in Listing~\ref{lst:avmsg}. Detailed explanation about the message types
+and according actions will be given in the following subsections.
+
+\begin{lstlisting}[label={lst:avmsg},caption={Available messages}]
+:: MTaskId :== Int
+:: MSDSId :== Int
+:: MTaskFreeBytes :== Int
+:: MTaskMSGRecv
+ = MTTaskAck MTaskId MTaskFreeBytes | MTTaskDelAck MTaskId
+ | MTSDSAck MSDSId | MTSDSDelAck MSDSId
+ | MTPub MSDSId BCValue | MTMessage String
+ | MTDevSpec MTaskDeviceSpec | MTEmpty
+
+:: MTaskMSGSend
+ = MTTask MTaskInterval String | MTTaskDel MTaskId
+ | MTShutdown | MTSds MSDSId BCValue
+ | MTUpd MSDSId BCValue | MTSpec
+
+:: MTaskInterval = OneShot | OnInterval Int | OnInterrupt Int
+\end{lstlisting}
+
+\subsection{Add a device}
+A device can be added by filling in the \CI{MTaskDevice} record as much as
+possible and running the \CI{connectDevice} function. This function grabs the
+channels, starts the synchronization \gls{Task} (\CI{synFun}), makes sure the
+errors are handled when needed and runs a processing function in parallel to
+react on the incoming messages. Moreover, it sends a specification request to
+the device in question to determine the details of the device and updates the
+record to contain the top-level \gls{Task}-id. All device functionality
+heavily depends on the specific \CI{deviceShare} function that generates an
+\gls{SDS} for a specific device. This allows giving an old device record to the
+function and still update the latest instance. Listing~\ref{lst:connectDevice}
+shows the connection function.
+
+\begin{lstlisting}[label={lst:connectDevice},%
+ caption={Connect a device}]
+connectDevice :: (MTaskDevice (Shared Channels) -> Task ()) MTaskDevice -> Task Channels
+connectDevice procFun device = set ([], [], False) ch
+ >>| appendTopLevelTask 'DM'.newMap True
+ ( procFun device ch -||- catchAll (getSynFun device.deviceData ch) errHdl)
+ >>= \tid->upd (\d->{d&deviceTask=Just tid,deviceError=Nothing}) (deviceShare device)
+ >>| upd (\(r,s,ss)->(r,s++[MTSpec],ss)) ch
+where
+ errHdl e = upd (\d->{d & deviceTask=Nothing, deviceError=Just e}) (deviceShare device) @! ()
+ ch = channels device
+\end{lstlisting}
+
+Figure~\ref{fig:handshake} shows the connection diagram. The client responds to
+the server with their device specification. This is detected by the processing
+function and the record is updated accordingly.
+
+\begin{figure}[H]
+ \centering
+ \begin{sequencediagram}
+ \newthread{s}{Server}
+ \newinst[4]{c}{Client}
+ \begin{call}{s}{MTSpec}{c}{MTDevSpec}
+ \end{call}
+ \end{sequencediagram}
+ \caption{Connect a device}\label{fig:handshake}
+\end{figure}
+
+\subsection{\glspl{Task} \& \glspl{SDS}}
+When a \gls{Task} is sent to the device it is added to the device record
+without an identifier. The actual identifier is added to the record when the
+acknowledgement of the \gls{Task} by the device is received. The connection
+diagram is shown in Figure~\ref{fig:tasksend}.
+
+\begin{figure}[H]
+ \centering
+ \begin{sequencediagram}
+ \newthread{s}{Server}
+ \newinst[4]{c}{Client}
+ \begin{call}{s}{MTSDS}{c}{MTSDSAck}
+ \end{call}
+ \begin{call}{s}{MTTask}{c}{MTTaskAck}
+ \end{call}
+ \end{sequencediagram}
+ \caption{Sending a \gls{Task} to a device}\label{fig:tasksend}
+\end{figure}
+
+The function for sending a \gls{Task} to the device is shown in
+Listing~\ref{lst:sendtask}. First the \gls{Task} is compiled into messages. The
+details of the compilation process are given in Section~\ref{sec:compiler}.
+The new \glspl{SDS} that were generated during compilation are merged with the
+existing device's \glspl{SDS}. Furthermore the messages are placed in the
+channel \gls{SDS} of the device. This will result in sending the actual \gls{SDS}
+specification and \gls{Task} specifications to the device. A \gls{Task} record
+is created with the identifier $-1$ to denote a \gls{Task} not yet
+acknowledged. Finally the device itself is updated with the new state and with
+the new \gls{Task}. After waiting for the acknowledgement the device is
+updated again and the \gls{Task} returns.
+
+\begin{lstlisting}[label={lst:sendtask},%
+ caption={Sending a \gls{Task} to a device}]
+makeTask :: String Int -> Task MTaskTask
+makeTask name ident = get currentDateTime @ \dt->{MTaskTask | name=name, ident=ident, dateAdded=dt}
+
+makeShare :: String Int BCValue -> MTaskShare
+makeShare withTask identifier value = {MTaskShare | withTask=[withTask], identifier=identifier, value=value}
+
+sendTaskToDevice :: String (Main (ByteCode a Stmt)) (MTaskDevice, MTaskInterval) -> Task MTaskTask
+sendTaskToDevice wta mTask (device, timeout)
+# (msgs, newState=:{sdss}) = toMessages timeout mTask device.deviceState
+# shares = [makeShare wta "" sdsi sdsval\\{sdsi,sdsval}<-sdss, (MTSds sdsi` _)<-msgs | sdsi == sdsi`]
+= updateShares device ((++) shares)
+ >>| sendMessages msgs device
+ >>| makeTask wta -1
+ >>= \t->upd (addTaskUpState newState t) (deviceShare device)
+ >>| wait "Waiting for task to be acked" (taskAcked t) (deviceShare device)
+ >>| treturn t
+where
+ addTaskUpState :: BCState MTaskTask MTaskDevice -> MTaskDevice
+ addTaskUpState st task device = {MTaskDevice | device & deviceState=st, deviceTasks=[task:device.deviceTasks]}
+ taskAcked t d = maybe True (\t->t.ident <> -1) $ find (eq t) d.deviceTasks
+ eq t1 t2 = t1.dateAdded == t2.dateAdded && t1.MTaskTask.name == t2.MTaskTask.name
+\end{lstlisting}
+
+\subsection{Miscellaneous Messages}
+One special type of message is available which is sent to the device only when
+it needs to reboot. When the server wants to stop the bond with the device it
+sends the \CI{MTShutdown} message. The device will then clear its memory, thus
+losing all the \glspl{SDS} and \glspl{Task} that were stored and reset itself.
+Shortly after the shutdown message a new server can connect to the device
+because the device is back in listening mode.
+
+\subsection{Integration}
+When the system starts up, the devices from the previous execution still
+residing in the \gls{SDS} must be cleaned up. It might be the case that they
+contain \glspl{Task}, \glspl{SDS} or errors that are no longer applicable in
+this run. A user or programmer can later choose to reconnect to some devices.
+
+\begin{lstlisting}[caption={Starting up the devices},%
+ label={lst:startupdevs}]
+startupDevices :: Task [MTaskDevice]
+startupDevices = upd (map reset) deviceStoreNP
+ where reset d = {d & deviceTask=Nothing, deviceTasks=[], deviceError=Nothing}
+\end{lstlisting}
+
+The system's management is done through the interface of a single \gls{Task}
+called \CI{mTaskManager}. To manage the system, a couple of different
+functionalities are necessary and are launched. An image of the management
+interface is shown in Figure~\ref{lst:manage}. The left sidebar of the
+interface shows the list of example \glspl{Task} that are present in the
+system. When clicking a \gls{Task}, a dialog opens in which a device can be
+selected to send the \gls{Task} to. The dialog might contain user specified
+variables. All example \gls{mTask}-\glspl{Task} are of the type \CI{Task (Main
+(ByteCode () Stmt))} and can thus ask for user input first if needed for
+parameterized \gls{mTask}-\glspl{Task}. The bottom panel shows the device
+information. In this panel, the devices can be created and modified. Moreover,
+this panel allows the user to reconnect with a device after a restart of the
+server application.
+
+\begin{figure}[H]
+ \centering
+ \includegraphics[width=\linewidth]{manage}
+ \caption{The device management interface}\label{lst:manage}
+\end{figure}
--- /dev/null
+A device is suitable for the system if it can run the engine.
+The engine is compiled from one codebase and devices implement (part of) the
+device specific interface. The shared codebase only uses standard \gls{C} and
+no special libraries or tricks are used. Therefore, the code is compilable for
+almost any device or system. Note that it is not needed to implement a full
+interface. The full interface --- excluding the device specific settings --- is
+listed in Appendix~\ref{app:device-interface}. The interface works in a
+similar fashion as the \gls{EDSL}. Devices do not have to implement all
+functionality, this is analogous to the fact that views do not have to
+implement all type classes in the \gls{EDSL}. When the device connects with
+the server for the first time, the specifications of what is implemented is
+communicated.
+
+At the time of writing the following device families are supported and can run
+the device software.
+\begin{itemize}
+ \item \texttt{POSIX} compatible systems connected via the \gls{TCP}.
+
+ This includes systems running \emph{Linux} and \emph{MacOS}.
+ \item The \texttt{STM32} microcontrollers family supported by
+ \texttt{ChibiOS} connected via serial communication.
+
+ This is tested in particular on the \texttt{STM32f7x} series \gls{ARM}
+ development board.
+ \item Microcontrollers which are programmable in the \gls{Arduino} \gls{IDE}
+ connected via serial communication or via \gls{TCP} over WiFi or
+ Ethernet.
+
+ This does not only include \gls{Arduino} compatible boards but also
+ other boards capable of running \gls{Arduino} code. A port of the
+ client has been made for the \texttt{ESP8266} powered \emph{NodeMCU}
+ that is connected via \gls{TCP} over WiFi. A port also has been made
+ for the regular \gls{Arduino} \emph{UNO} board which only boasts a
+ meager \emph{2K} \emph{RAM}. The stack size and storage available for
+ devices boasting this little \emph{RAM} has to be smaller than default
+ but are still suitable to hold a hand full of \glspl{Task}.
+\end{itemize}
+
+\subsection{Client}
+\subsubsection{Engine}
+The client is in a constant loop listening for input and waiting to execute
+\glspl{Task}. The pseudocode for this is shown in Algorithm~\ref{alg:client}.
+The \CI{input\_available} function waits for input, but has a timeout set which
+can be interrupted. The timeout of the function determines the amount of loops
+per time interval and is a parameter that can be set during compilation for a
+device.
+
+\begin{algorithm}
+ \KwData{
+ \textbf{list} $tasks$,
+ \textbf{time} $tm$
+ }
+
+ \Begin{
+ \While{true}{
+ \If{input\_available$()$}{
+ receive\_data()\;
+ }
+
+ $tm\leftarrow \text{now}()$\;
+ \ForEach{$t\leftarrow tasks$}{
+ \uIf{is\_interrupt$(t)$ \textbf{and} had\_interrupt$(t)$}{
+ run\_task$(t)$\;
+ }
+ \ElseIf{$tm-t.\text{lastrun} > t.\text{interval}$}{
+ run\_task$(t)$\;
+ \uIf{$t.\text{interval}==0$}{
+ delete\_task$(t)$\;
+ }\Else{
+ $t.\text{lastrun}\leftarrow t$\;
+ }
+ }
+ }
+ }
+ }
+ \caption{Engine pseudocode}\label{alg:client}
+\end{algorithm}
+
+\subsubsection{Storage}
+\glspl{Task} and \glspl{SDS} are stored on the client in memory. Some devices
+have very little memory and therefore memory space is very expensive and needs
+to be used optimally. Almost all microcontrollers support heaps nowadays,
+however, the functions for allocating and freeing the memory on the heap are
+not very space optimal and often leave holes in the heap if allocations are not
+freed in reverse order. To overcome this problem the client will allocate a big
+memory segment in the global data block. This block of memory resides under the
+stack and its size can be set in the interface implementation. This block of
+memory will be managed in a similar way as the entire memory space of the
+device is managed. \Glspl{Task} will grow from the bottom up and \glspl{SDS}
+will grow from the top down.
+
+When a \gls{Task} is received, the program will traverse the memory space from
+the bottom up, jumping over all \glspl{Task}. A \gls{Task} is stored as the
+structure followed directly by its bytecode. Therefore it only takes two jumps
+to determine the size of the \gls{Task}. When the program arrived at the last
+\gls{Task}, this place is returned and the newly received \gls{Task} can be
+copied to there. This method is analogously applied for \glspl{SDS}, however,
+the \glspl{SDS} grow from the bottom down.
+
+When a \gls{Task} or \gls{SDS} is removed, all remaining objects are compressed
+again. This means that if the first received \gls{Task} is removed, all
+\glspl{Task} received later will have to move back. Obviously, this is quite
+time intensive but it can not be permitted to leave holes in the memory since
+the memory space is so limited. This techniques allows for even the smallest
+tested microcontrollers with only $2K$ \emph{RAM} to hold several \glspl{Task}
+and \glspl{SDS}. If this technique would not be used the memory space will
+decrease over time and the client can then not run for very long since holes
+are evidently created at some point.
+
+The structure instances and helper functions for traversing them in memory for
+\glspl{Task} and \glspl{SDS} are shown in Listing~\ref{lst:structs}.
+
+\begin{lstlisting}[language=C,label={lst:structs},%
+ caption={The data type storing the \glspl{Task}},float]
+struct task {
+ uint16_t tasklength;
+ uint16_t interval;
+ unsigned long lastrun;
+ uint8_t taskid;
+ uint8_t *bc;
+};
+
+struct task *task_head(void);
+struct task *task_next(struct task *t);
+
+struct sds {
+ int id;
+ int value;
+ char type;
+};
+
+struct sds *sds_head(void);
+struct sds *sds_next(struct sds *s);
+\end{lstlisting}
+
+\subsubsection{Interpretation}
+The execution of a \gls{Task} is started by running the \CI{run\_task} function
+and always starts with setting the program counter and stack
+pointer to zero and the bottom respectively. When finished, the
+interpreter executes one step at the time while the program counter is smaller
+than the program length. This code is listed in Listing~\ref{lst:interpr}. One
+execution step is basically a big switch statement going over all possible
+bytecode instructions. Of some instructions, the implementations are shown in
+the listing. The \CI{BCPush} instruction is a little more complicated in the
+real code because some decoding will take place as not all \CI{BCValue}s are of
+the same length and are encoded.
+
+\begin{lstlisting}[language=C,label={lst:interpr},%
+ caption={Rough code outline for interpretation}]
+#define f16(p) program[pc]*265+program[pc+1]
+
+void run_task(struct task *t){
+ uint8_t *program = t->bc;
+ int plen = t->tasklength;
+ int pc = 0;
+ int sp = 0;
+ while(pc < plen){
+ switch(program[pc++]){
+ case BCNOP:
+ break;
+ case BCPUSH:
+ stack[sp++] = pc++ //Simplified
+ break;
+ case BCPOP:
+ sp--;
+ break;
+ case BCSDSSTORE:
+ sds_store(f16(pc), stack[--sp]);
+ pc+=2;
+ break;
+ // ...
+ case BCADD: trace("add");
+ stack[sp-2] = stack[sp-2] + stack[sp-1];
+ sp -= 1;
+ break;
+ // ...
+ case BCJMPT: trace("jmpt to %d", program[pc]);
+ pc = stack[--sp] ? program[pc]-1 : pc+1;
+ break;
+}
+\end{lstlisting}
+
+\subsection{Specification}
+The server stores a description for every device available in a record type.
+From the macro settings in the interface file, a profile is created that
+describes the specification of the device. When the connection between the
+server and a client is established, the server will send a request for
+specification. The client serializes its specification and send it to the
+server so that the server knows what the client is capable of. The exact
+specification is shown in Listing~\ref{lst:devicespec} and stores the
+peripheral availability, the memory available for storing \glspl{Task} and
+\glspl{SDS} and the size of the stack.
+
+\begin{lstlisting}[label={lst:devicespec},
+ caption={Device specification for \gls{mTask}-\glspl{Task}}]
+:: MTaskDeviceSpec =
+ { haveLed :: Bool
+ , haveLCD :: Bool
+ , have...
+ , bytesMemory :: Int
+ , stackSize :: Int
+ , aPins :: Int
+ , dPins :: Int
+ }
+\end{lstlisting}
--- /dev/null
+Here comes a description of the demo program.
--- /dev/null
+The server part of the system is written in \gls{iTasks}. Functions for
+managing devices, \glspl{Task} and \glspl{SDS} have been created to support the
+functionality. An interactive web application has been created that provides an
+interactive management console for the \gls{mTask} system. This interface
+provides functionality to list \glspl{SDS}, add and remove \glspl{Task},
+administrate devices and view the state of the system.
+
+\subsection{Device Storage}
+Everything that a device encompasses is stored in the \CI{MTaskDevice} record
+type. This includes management for the \glspl{SDS} and \glspl{Task} stored on
+the device. The \CI{MTaskDevice} definition is shown in
+Listing~\ref{lst:mtaskdevice} accompanied with the necessary classes and sub
+types.
+
+\begin{lstlisting}[caption={Device type},label={lst:mtaskdevice}]
+:: Channels :== ([MTaskMSGRecv], [MTaskMSGSend], Bool)
+:: BCState = ... // Compiler state, explained in later sections
+:: MTaskResource
+ = TCPDevice TCPSettings
+ | SerialDevice TTYSettings
+ | ...
+:: MTaskDevice =
+ { deviceTask :: Maybe TaskId
+ , deviceError :: Maybe String
+ , deviceChannels :: String
+ , deviceName :: String
+ , deviceState :: BCState
+ , deviceTasks :: [MTaskTask]
+ , deviceResource :: MTaskResource
+ , deviceSpec :: Maybe MTaskDeviceSpec
+ , deviceShares :: [MTaskShare]
+ }
+
+channels :: MTaskDevice -> Shared Channels
+
+class MTaskDuplex a where
+ synFun :: a (Shared Channels) -> Task ()
+\end{lstlisting}
+
+The \CI{deviceResource} component of the record must implement the
+\CI{MTaskDuplex} interface that provides a function that launches a \gls{Task}
+used for synchronizing the channels. The \CI{deviceTask} stores the
+\gls{Task}-id for this \gls{Task} when active so that it can be checked upon.
+This top-level task has the duty to report exceptions and errors as they are
+thrown by setting the \CI{deviceError} field. All communication goes via these
+channels. To send a message to the device, the system just puts it
+in the channels. Messages sent from the client to the server are also placed
+in there. In the case of the \gls{TCP} device type, the \gls{Task} is just a
+simple wrapper around the existing \CI{tcpconnect} function in \gls{iTasks}. In
+case of a device connected by a serial connection, it uses the newly developed
+serial port library of \gls{Clean}\footnote{\url{%
+https://gitlab.science.ru.nl/mlubbers/CleanSerial}}.
+
+Besides all the communication information, the record also keeps track of the
+\glspl{Task} currently on the device, the compiler state (see
+Section~\ref{sec:compiler}) and the according \glspl{SDS}. Finally, it stores
+the specification of the device that is received when connecting. All of this
+is given in Listing~\ref{lst:mtaskdevice}. The definitions of the message
+format are explained in the following section.
+
+\subsection{Shares}
+The system keeps track of the \glspl{SDS} stored on
+the client in a big \gls{SDS} containing a list of devices. Client-\glspl{SDS}
+can be stored on one device at the same time. This means that if an \gls{SDS}
+updates, everyone watching it will be notified. This would result in a lot
+of notifications that are not meant for the watcher. Moreover, when a client
+updates the \gls{SDS} this is processed by the connection handler and results
+in an update of the real \gls{SDS}. Finally, the \gls{SDS} of a client must be
+synchronized with the actual device. Thus, when an \gls{iTasks}-\gls{Task}
+writes the client-\gls{SDS}, it must be propagated to the real device. There
+are several ways of tackling this problem each with their own level of
+granularity.
+
+First an actual \gls{iTasks}-\gls{SDS} for every \gls{SDS} used in a client can
+be instantiated with one \gls{iTasks}-\gls{Task} listening to the \gls{SDS} and
+synchronizing it with the device when an update occurred. This approach is very
+expensive as it requires a lot of listening \glspl{Task}.
+
+Improved on this, a single \gls{iTasks}-\gls{SDS} can be created for every
+devices that stores the respective \glspl{SDS}. Using the \CI{mapReadWrite}
+functions, a single \gls{SDS} per device can be created as a lens that allows
+mapping on a single client-\gls{SDS}. However, this approach still requires
+\glspl{Task} listening to the \gls{SDS} and when an \gls{SDS} is written,
+everyone is notified, even if the \gls{Task} only uses the value of a single
+different \gls{SDS}.
+
+Finally, the current approach --- a single \gls{SDS} for the entire system
+--- was explored. To create \glspl{SDS} per device or per client-\glspl{SDS} a
+\CI{mapReadWrite} can be used but it suffers from the same problem as mentioned
+before. Moreover, a \gls{Task} still has to watch the \gls{SDS} and communicate
+the client-\gls{SDS} updates to the actual device. Both of these problems can
+be solved by using a tailor made \gls{SDS} that heavily depends on parametric
+lenses.
+
+\subsection{Parametric Lenses}
+The type for the parametric lens of the big \gls{SDS} is \CI{Maybe
+(MTaskDevice, Int)}. The \gls{SDS} is responsible for storing the entire list
+of devices, from now on global. Moreover, the \gls{SDS} can focus on a single
+device, from now on local. A local \gls{SDS} can also specifically focus on a
+single \gls{SDS} on a single device, from now on called local-share. The
+implementation of the real \gls{SDS} is given in Listing~\ref{lst:actualdev}.
+The \gls{SDS} is a lens on an actual \gls{SDS} that writes to a file or memory.
+Reading the \gls{SDS} is nothing more than reading the real \gls{SDS}. Writing
+the \gls{SDS} is a little bit more involved. If the write operation originated
+from an \gls{SDS} focussed on a single client-\gls{SDS}, the write action must
+also be relayed to the actual device. If the write originated from an \gls{SDS}
+focussed the devices or on one device only, nothing needs to be done. The
+notification predicate determines whether a watcher gets a notification update.
+
+\begin{lstlisting}[label={lst:actualdev},%
+ caption={Device \gls{SDS}}]
+deviceStore :: RWShared (Maybe (MTaskDevice, Int)) [MTaskDevice] [MTaskDevice]
+deviceStore = SDSSource {SDSSource | name="deviceStore", read = realRead, write= realWrite}
+where
+ realRead :: (Maybe (MTaskDevice,Int)) *IWorld -> (MaybeError TaskException [MTaskDevice], *IWorld)
+ realRead p iw = read realDeviceStore iw
+
+ realWrite :: (Maybe (MTaskDevice,Int)) [MTaskDevice] *IWorld -> (MaybeError TaskException (SDSNotifyPred (Maybe (MTaskDevice,Int))), *IWorld)
+ realWrite mi w iw
+ # (merr, iw) = write w realDeviceStore iw
+ | isError merr || isNothing mi = (merr $> notifyPred mi, iw)
+ # (Just (dev, ident)) = mi
+ | ident == -1 = (merr $> notifyPred mi, iw)
+ = case find ((==)dev) w of
+ Nothing = (Error $ exception "Device lost", iw)
+ Just {deviceShares} = case find (\d->d.identifier == ident) deviceShares of
+ Nothing = (Error $ exception "Share lost", iw)
+ Just s = case sendMessagesIW [MTUpd ident s.MTaskShare.value] dev iw of
+ (Error e, iw) = (Error e, iw)
+ (Ok _, iw) = (Ok $ notifyPred mi, iw)
+
+ notifyPred :: (Maybe (MTaskDevice, Int)) (Maybe (MTaskDevice, Int)) -> Bool
+ notifyPred Nothing Nothing = True // Global watcher looking at a global event
+ notifyPred Nothing (Just _) = False // Global watcher looking at a local event
+ notifyPred (Just _) Nothing = False // Local watcher looking at a global event
+ // Local device watcher looking at a local event
+ notifyPred (Just (d1, -1)) (Just (d2, _)) = d1 == d2
+ // Local share watcher looking at a local share event
+ notifyPred (Just (d1, i1)) (Just (d2, i2)) = d1 == d2 && i1 == i2
+
+ realDeviceStore :: Shared [MTaskDevice]
+ realDeviceStore = sharedStore "mTaskDevices" []
+\end{lstlisting}
+
+\subsubsection{Global \glspl{SDS}}
+Accessing the global \gls{SDS} is just a matter of focussing the
+\CI{deviceStore} with the \CI{Nothing} parameter as follows:
+
+\begin{lstlisting}[caption={Global \gls{SDS}}]
+deviceStoreNP :: Shared [MTaskDevice]
+deviceStoreNP = sdsFocus Nothing deviceStore
+\end{lstlisting}
+
+\subsubsection{Local \glspl{SDS}}
+Accessing a single device can be done using the \CI{mapReadWrite} function.
+Since device comparison is shallow, the device that is given is allowed to be
+an old version. The identification of devices is solely done on the name of the
+channels and is unique throughout the system. The implementation is as follows:
+
+\begin{lstlisting}[caption={Local \gls{SDS}}]
+deviceShare :: MTaskDevice -> Shared MTaskDevice
+deviceShare d = mapReadWriteError
+ ( \ds->case find ((==)d) of
+ Nothing = exception "Device lost"
+ Just d = Ok d)
+ , \w ds->case splitWith ((==)d) ds of
+ ([], _) = Error $ exception "Device lost"
+ ([_:_], ds) = Ok $ Just [w:ds])
+ $ sdsFocus (Just (d, -1)) deviceStore
+\end{lstlisting}
+
+\subsubsection{Local-\gls{SDS} specific \glspl{SDS}}
+A single \gls{SDS} on a single device can be accessed using the \CI{shareShare}
+function. This function focusses the real big \gls{SDS} on a single \gls{SDS}
+and uses the \CI{mapReadWrite} functions to serve the correct part of the
+information.
+
+\begin{lstlisting}[caption={Local \gls{SDS}}]
+shareShare :: MTaskDevice MTaskShare -> Shared BCValue
+shareShare dev share = sdsFocus ()
+ $ mapReadWriteError (read, write)
+ $ sdsFocus (Just (dev, share.identifier))
+ $ deviceStore
+where
+ read :: [MTaskDevice] -> MaybeError TaskException BCValue
+ read devs = case find ((==)dev) devs of
+ Nothing = exception "Device lost"
+ Just d = case find ((==)share) d.deviceShares of
+ Nothing = exception "Share lost"
+ Just s = Ok s.MTaskShare.value
+
+ write :: BCValue [MTaskDevice] -> MaybeError TaskException (Maybe [MTaskDevice])
+ write val devs = case partition ((==)dev) devs of
+ ([], _) = Error $ exception "Device doesn't exist anymore"
+ ([_,_:_], _) = Error $ exception "Multiple matching devices"
+ ([d=:{deviceShares}], devs) = case partition ((==)share) deviceShares of
+ ([], _) = Error $ exception "Share doesn't exist anymore"
+ ([_,_:_], _) = Error $ exception "Multiple matching shares"
+ ([s], shares) = Ok $ Just [{MTaskDevice | d &
+ deviceShares=[{MTaskShare | s & value=val}:shares]}:devs]
+\end{lstlisting}
--- /dev/null
+If the user does not want to know where and when a \gls{mTask} is actually
+executed and is just interested in the results it can lift the \gls{mTask} to
+an \gls{iTasks}-\gls{Task}. The function is called with a name, \gls{mTask},
+device and interval specification and it will return a \gls{Task} that finishes
+if and only if the \gls{mTask} has returned.
+
+\begin{lstlisting}[caption={Starting up the devices}]
+liftmTask :: String (Main (ByteCode () Stmt)) (MTaskDevice, MTaskInterval) -> Task ()
+liftmTask wta mTask c=:(dev, _)= sendTaskToDevice wta mTask c
+ >>= \t->wait "Waiting for mTask to return" (taskRemoved t) (deviceShare dev)
+ >>| viewInformation "Done!" [] ()
+where
+ taskRemoved t d = isNothing $ find (\t1->t1.ident==t.ident) d.deviceTasks
+\end{lstlisting}
--- /dev/null
+The goal of the system as a whole is to offer a framework of functions with
+which an \gls{iTasks}-system can add, change and remove devices at runtime.
+Moreover, the \gls{iTasks}-system can send \gls{mTask}-\glspl{Task} ---
+compiled at runtime to bytecode by the \gls{mTask}-view --- to the device. The
+device runs an interpreter which can execute the \gls{Task}'s bytecode. Device
+profiles should be persistent during reboots of the \gls{iTasks}-system. The
+methods of interacting with \gls{mTask}-\gls{Task} should be analogous to
+interacting with \gls{iTasks}-\glspl{Task}. This means that programmers can
+access the \glspl{SDS} made for a device in the same way as regular \glspl{SDS}
+and they can execute \gls{mTask}-\glspl{Task} as if they where normal
+\gls{iTasks}-\glspl{Task}.
+
+The following terms will be used throughout the following chapter:
+\begin{itemize}
+ \item Device, Client
+
+ These terms denotes the actual device connected to the system. This can
+ be a real device such as a microcontroller but it can also just be a
+ program on the same machine as the server functioning as a client.
+ \item Server, \gls{iTasks}-System
+
+ This is the actual executable serving the \gls{iTasks} application. The
+ system contains \glspl{Task} taking care of the communication with the
+ clients.
+ \item System
+
+ The system describes the complete ecosystem, containing both the server
+ and the clients including the communication between them.
+ \item Engine
+
+ The runtime system of the client is called the engine. This program
+ handles communicating with the server and runs the interpreter for the
+ \glspl{Task} on the client.
+\end{itemize}
+
+\section{Devices}
+\input{arch.devices}
+
+\section{iTasks}
+\input{arch.itasks}
+
+\section{Communication}
+\input{arch.communication}
+
+\section[Lifting mTasks to iTasks-Tasks]%
+ {Lifting \gls{mTask}-\glspl{Task} to \gls{iTasks}-\glspl{Task}}
+\input{arch.lift}
+
+\section{Example}
+\input{arch.example}
--- /dev/null
+This thesis introduces a novel system for adding \gls{IoT} functionality to
+the \gls{TOP} implementation \gls{iTasks}. A new view for the existing
+\gls{mTask}-\gls{EDSL} has been created which compiles the program
+into bytecode that can be interpreted by a client. Clients have
+been written for several microcontrollers and consumer architectures which can
+be connected through various means of communication such as serial port,
+wifi and wired network communication. The bytecode on the devices is
+interpreted using a stack machine and provides the programmer with interfaces
+to the peripherals. The semantics for \gls{mTask} try to resemble the
+\gls{iTasks} semantics as close as possible.
+
+The host language has a proven efficient compiler and code generator. The
+compilation is linear in the amount of instructions generated and is therefore
+also scalable. Moreover, compiling \glspl{Task} is fast because it is nothing
+more than running some functions native to the host language and there is no
+intermediate \gls{AST}.
+
+The dynamic nature of the client allows the microcontroller to be programmed
+once and used many times. The program memory of microcontrollers often
+guarantees around $10.000$ write or upload cycles and therefore existing
+techniques such as generating \gls{C} code are not suitable for dynamic
+\gls{Task} environments. The dynamic nature also allows the programmer to
+design fail-over mechanisms. When a device is assigned a \gls{Task} but another
+device suddenly becomes unusable, the \gls{iTasks} system can reassign a new
+\gls{mTask}-\gls{Task} to another device that is also suitable for running the
+\gls{Task} without needing to recompile the code.
--- /dev/null
+The system is still a crude prototype and a proof of concept. Improvements and
+extension for the system are amply available in several fields of study.
+
+\subsection{Simulation}
+An additional simulation view to the \gls{mTask}-\gls{EDSL} could be added that
+works in the same way as the existing \gls{C}-backed simulation. It simulates
+the bytecode interpretation. Moreover, it would also be possible to let the
+simulator function as a real device, thus handling all communication through
+the existing \gls{SDS}-based systems. At the moment the \emph{POSIX}-client is
+the reference client and contains debugging code. Adding a simulation view to
+the system allows for easy interactive debugging. However, it might not be
+easy to devise a simulation tool that accurately simulates the \gls{mTask}
+system on some levels. The semantics can be simulated but timing and peripheral
+input/output are more difficult to simulate properly.
+
+\subsection{Optimization}
+\paragraph{Multitasking on the client:}
+True multitasking could be added to the client software. This allows
+\gls{mTask}-\glspl{Task} to run truly parallel. All \gls{mTask}-\glspl{Task}
+get slices of execution time and will each have their own interpreter state
+instead of a single system-wide state which is reset after am \gls{mTask}
+finishes. This does require separate stacks for each \gls{Task} and therefore
+increases the system requirements of the client software. However, it could be
+implemented as a compile-time option and exchanged during the handshake so that
+the server knows the multithreading capabilities of the client. Multithreading
+allows \glspl{Task} to be truly interruptible by other \glspl{Task}.
+Furthermore, this allows for more fine-grained timing control of \glspl{Task}.
+
+\paragraph{Optimizing the interpreter:}
+Due to time constraints and focus, hardly any work has been done in the
+interpreter. The current interpreter is a no nonsense stack machine. A lot of
+improvements can be done in this part. For example, precomputed \emph{gotos}
+can improve jumping to the correct part of the code corresponding to the
+correct instruction. Moreover, the stack currently consists of 16-bit values.
+All operations work on 16-bit values and this simplifies the interpreter
+implementation. A memory improvement can be made by converting the stack to
+8-bit values. This does pose some problems since an equality instruction must
+work on single-byte booleans \emph{and} two-byte integers. Adding specialized
+instructions per word size could overcome this problem.
+
+\subsection{Resources}
+\paragraph{Resource analysis: }
+Resource analysis during compilation can be useful to determine if an
+\gls{mTask}-\gls{Task} is suitable for a specific device. If the device does
+not contain the correct peripherals --- such as an \gls{LCD} --- then the
+\gls{mTask}-\gls{Task} should be rejected and feedback to the user must be
+given. It might even be possible to do this statically on the type level. The
+current system does not have any of this built-in. Sending a \gls{Task} that
+uses the \gls{LCD} to a device not containing one will result in the device
+just skipping the \gls{LCD} related instructions.
+
+\paragraph{Extended resource analysis: }
+The previous idea could be extended to the analysis of stack size and possibly
+communication bandwidth. With this functionality ever more reliable fail-over
+systems can be designed. When the system knows precise bounds it can allocate
+more \glspl{Task} on a device whilst staying within safe memory bounds. The
+resource allocation can be done at runtime within the backend itself or a
+general backend can be devised that can calculate the resources needed for a
+given \gls{mTask}. A specific \gls{mTask} cannot have multiple views at the
+same time due to the restrictions of class based shallow embedding. It might
+even be possible to encode the resource allocation in the type system itself
+using forms of dependant types.
+
+\subsection{Functionality}
+\paragraph{Add more combinators: }
+More \gls{Task}-combinators --- already existing in the \gls{iTasks}-system ---
+could be added to the \gls{mTask}-system to allow for more fine-grained control
+flow between \gls{mTask}-\glspl{Task}. In this way the new system follows the
+\gls{TOP} paradigm even more and makes programming \gls{mTask}-\glspl{Task} for
+\gls{TOP}-programmers more seamless. Some of the combinators require previously
+mentioned extension such as the parallel combinator. Others might be achieved
+using simple syntactic transformations.
+
+\paragraph{Launch \glspl{Task} from a \gls{Task}:}
+Currently the \gls{C}-view allows \glspl{Task} to launch other \glspl{Task}. In
+the current system this type of logic has to take place on the server side.
+Adding this functionality to the bytecode-view allows greater flexibility,
+easier programming and less communication resources. Adding these semantics
+requires modifications to the client software and extensions to the
+communication protocol since relations between \glspl{Task} also need to be
+encoded and communicated.
+
+The \gls{SDS} functionality in the current system is bare. There is no easy way
+of reusing an \gls{SDS} for another \gls{Task} on the same device or on another
+device. Such functionality can be implemented in a crude way by tying the
+\glspl{SDS} together in the \gls{iTasks} environment. However, this will result
+in a slow updating system. Functionality for reusing shares from a device
+should be added. This requires rethinking the storage because some typedness is
+lost when the \gls{SDS} is stored after compilation. A possibility would be to
+use runtime typing with \CI{Dynamic}s or the encoding technique currently used
+for \CI{BCValue}s. Using \glspl{SDS} for multiple \glspl{Task} within one
+device is solved when the previous point is implemented.
+
+\subsection{Robustness}
+\paragraph{Reconnect with lost devices:}
+The robustness of the system can be greatly improved. Devices that lose
+connection are not well supported in the current system. The device will stop
+functioning and has to be emptied for a reconnect. \Glspl{Task} residing on a
+device that disconnected should be kept on the server to allow a swift
+reconnect and restoration of the \glspl{Task}. This holds the same for the
+client software. The client drops all existing \glspl{Task} on a shutdown
+request. An extra specialization of the shutdown could be added that drops the
+connection but keeps the \glspl{Task} in memory. During the downtime the
+\glspl{Task} can still be executed but publications need to be delayed. If the
+same server connects to the client the delayed publications can be sent
+anyways.
+
+\paragraph{Reverse \gls{Task} sending:}
+Furthermore, devices could send their current \glspl{Task} back to the
+server to synchronize it. This allows interchanging servers without
+interrupting the client. Allowing the client to send \glspl{Task} to the server
+is something to handle with care because it can easily cause high bandwidth
+usage.
\section{Discussion \& Future Research}
-The system is still a crude prototype and a proof of concept. Improvements and
-extension for the system are amply available in several fields of study.
-
-\subsection{Simulation}
-An additional simulation view to the \gls{mTask}-\gls{EDSL} could be added that
-works in the same way as the existing \gls{C}-backed simulation. It simulates
-the bytecode interpretation. Moreover, it would also be possible to let the
-simulator function as a real device, thus handling all communication through
-the existing \gls{SDS}-based systems. At the moment the \emph{POSIX}-client is
-the reference client and contains debugging code. Adding a simulation view to
-the system allows for easy interactive debugging. However, it might not be
-easy to devise a simulation tool that accurately simulates the \gls{mTask}
-system on some levels. The semantics can be simulated but timing and peripheral
-input/output are more difficult to simulate properly.
-
-\subsection{Optimization}
-\paragraph{Multitasking on the client:}
-True multitasking could be added to the client software. This allows
-\gls{mTask}-\glspl{Task} to run truly parallel. All \gls{mTask}-\glspl{Task}
-get slices of execution time and will each have their own interpreter state
-instead of a single system-wide state which is reset after am \gls{mTask}
-finishes. This does require separate stacks for each \gls{Task} and therefore
-increases the system requirements of the client software. However, it could be
-implemented as a compile-time option and exchanged during the handshake so that
-the server knows the multithreading capabilities of the client. Multithreading
-allows \glspl{Task} to be truly interruptible by other \glspl{Task}.
-Furthermore, this allows for more fine-grained timing control of \glspl{Task}.
-
-\paragraph{Optimizing the interpreter:}
-Due to time constraints and focus, hardly any work has been done in the
-interpreter. The current interpreter is a no nonsense stack machine. A lot of
-improvements can be done in this part. For example, precomputed \emph{gotos}
-can improve jumping to the correct part of the code corresponding to the
-correct instruction. Moreover, the stack currently consists of 16-bit values.
-All operations work on 16-bit values and this simplifies the interpreter
-implementation. A memory improvement can be made by converting the stack to
-8-bit values. This does pose some problems since an equality instruction must
-work on single-byte booleans \emph{and} two-byte integers. Adding specialized
-instructions per word size could overcome this problem.
-
-\subsection{Resources}
-\paragraph{Resource analysis: }
-Resource analysis during compilation can be useful to determine if an
-\gls{mTask}-\gls{Task} is suitable for a specific device. If the device does
-not contain the correct peripherals --- such as an \gls{LCD} --- then the
-\gls{mTask}-\gls{Task} should be rejected and feedback to the user must be
-given. It might even be possible to do this statically on the type level. The
-current system does not have any of this built-in. Sending a \gls{Task} that
-uses the \gls{LCD} to a device not containing one will result in the device
-just skipping the \gls{LCD} related instructions.
-
-\paragraph{Extended resource analysis: }
-The previous idea could be extended to the analysis of stack size and possibly
-communication bandwidth. With this functionality ever more reliable fail-over
-systems can be designed. When the system knows precise bounds it can allocate
-more \glspl{Task} on a device whilst staying within safe memory bounds. The
-resource allocation can be done at runtime within the backend itself or a
-general backend can be devised that can calculate the resources needed for a
-given \gls{mTask}. A specific \gls{mTask} cannot have multiple views at the
-same time due to the restrictions of class based shallow embedding. It might
-even be possible to encode the resource allocation in the type system itself
-using forms of dependant types.
-
-\subsection{Functionality}
-\paragraph{Add more combinators: }
-More \gls{Task}-combinators --- already existing in the \gls{iTasks}-system ---
-could be added to the \gls{mTask}-system to allow for more fine-grained control
-flow between \gls{mTask}-\glspl{Task}. In this way the new system follows the
-\gls{TOP} paradigm even more and makes programming \gls{mTask}-\glspl{Task} for
-\gls{TOP}-programmers more seamless. Some of the combinators require previously
-mentioned extension such as the parallel combinator. Others might be achieved
-using simple syntactic transformations.
-
-\paragraph{Launch \glspl{Task} from a \gls{Task}:}
-Currently the \gls{C}-view allows \glspl{Task} to launch other \glspl{Task}. In
-the current system this type of logic has to take place on the server side.
-Adding this functionality to the bytecode-view allows greater flexibility,
-easier programming and less communication resources. Adding these semantics
-requires modifications to the client software and extensions to the
-communication protocol since relations between \glspl{Task} also need to be
-encoded and communicated.
-
-The \gls{SDS} functionality in the current system is bare. There is no easy way
-of reusing an \gls{SDS} for another \gls{Task} on the same device or on another
-device. Such functionality can be implemented in a crude way by tying the
-\glspl{SDS} together in the \gls{iTasks} environment. However, this will result
-in a slow updating system. Functionality for reusing shares from a device
-should be added. This requires rethinking the storage because some typedness is
-lost when the \gls{SDS} is stored after compilation. A possibility would be to
-use runtime typing with \CI{Dynamic}s or the encoding technique currently used
-for \CI{BCValue}s. Using \glspl{SDS} for multiple \glspl{Task} within one
-device is solved when the previous point is implemented.
-
-\subsection{Robustness}
-\paragraph{Reconnect with lost devices:}
-The robustness of the system can be greatly improved. Devices that lose
-connection are not well supported in the current system. The device will stop
-functioning and has to be emptied for a reconnect. \Glspl{Task} residing on a
-device that disconnected should be kept on the server to allow a swift
-reconnect and restoration of the \glspl{Task}. This holds the same for the
-client software. The client drops all existing \glspl{Task} on a shutdown
-request. An extra specialization of the shutdown could be added that drops the
-connection but keeps the \glspl{Task} in memory. During the downtime the
-\glspl{Task} can still be executed but publications need to be delayed. If the
-same server connects to the client the delayed publications can be sent
-anyways.
-
-\paragraph{Reverse \gls{Task} sending:}
-Furthermore, devices could send their current \glspl{Task} back to the
-server to synchronize it. This allows interchanging servers without
-interrupting the client. Allowing the client to send \glspl{Task} to the server
-is something to handle with care because it can easily cause high bandwidth
-usage.
+\input{conclusion.discussion}
\section{Conclusion}
-This thesis introduces a novel system for adding \gls{IoT} functionality to
-the \gls{TOP} implementation \gls{iTasks}. A new view for the existing
-\gls{mTask}-\gls{EDSL} has been created which compiles the program
-into bytecode that can be interpreted by a client. Clients have
-been written for several microcontrollers and consumer architectures which can
-be connected through various means of communication such as serial port,
-wifi and wired network communication. The bytecode on the devices is
-interpreted using a stack machine and provides the programmer with interfaces
-to the peripherals. The semantics for \gls{mTask} try to resemble the
-\gls{iTasks} semantics as close as possible.
-
-The host language has a proven efficient compiler and code generator. The
-compilation is linear in the amount of instructions generated and is therefore
-also scalable. Moreover, compiling \glspl{Task} is fast because it is nothing
-more than running some functions native to the host language and there is no
-intermediate \gls{AST}.
-
-The dynamic nature of the client allows the microcontroller to be programmed
-once and used many times. The program memory of microcontrollers often
-guarantees around $10.000$ write or upload cycles and therefore existing
-techniques such as generating \gls{C} code are not suitable for dynamic
-\gls{Task} environments. The dynamic nature also allows the programmer to
-design fail-over mechanisms. When a device is assigned a \gls{Task} but another
-device suddenly becomes unusable, the \gls{iTasks} system can reassign a new
-\gls{mTask}-\gls{Task} to another device that is also suitable for running the
-\gls{Task} without needing to recompile the code.
+\input{conclusion.conclusion}
--- /dev/null
+The third type of embedding is called class-based shallow embedding and has the
+advantages of both shallow and deep
+embedding~\cite{svenningsson_combining_2012}. In class-based shallow embedding
+the language constructs are defined as type classes. This language is shown
+with the new method in Listing~\ref{lst:exclassshallow}.
+
+This type of embedding inherits the ease of adding views from shallow
+embedding. A view is just a different data type implementing one or more of the
+type classes as shown in the aforementioned Listing where an evaluator and a
+pretty printer are implemented.
+
+Just as with \glspl{GADT}, type safety is guaranteed in deep embedding. Type
+constraints are enforced through phantom types. One can add as many phantom
+types as necessary. Lastly, extensions can be added easily, just as in
+shallow embedding. When an extension is made in an existing class, all views
+must be updated accordingly to prevent possible runtime errors. When an
+extension is added in a new class, this problem does not arise and views can
+choose to implement only parts of the collection of classes.
+
+In contrast to deep embedding, it is very well possible to have multiple views
+applied on the same expression. This is also shown in the following listing.
+
+\begin{lstlisting}[label={lst:exclassshallow},%
+ caption={A minimal class based shallow \gls{EDSL}}]
+:: Env = ... // Some environment
+:: Evaluator a = Evaluator (Env -> a)
+:: PrettyPrinter a = PP String
+
+class intArith where
+ lit :: t -> v t | toString t
+ add :: (v t) (v t) -> (v t) | + t
+ minus :: (v t) (v t) -> (v t) | - t
+
+class boolArith where
+ and :: (v Bool) (v Bool) -> (v Bool)
+ eq :: (v t) (v t) -> (v Bool) | == t
+
+instance intArith Evaluator where
+ lit x = \e->x
+ add x y = ...
+
+instance intArith PrettyPrinter where
+ lit x = toString x
+ add x y = x +++ "+" +++ y
+ ...
+
+...
+
+Start :: (PP String, Bool)
+Start = (print e0, eval e0)
+where
+ e0 :: a Bool | intArith, boolArith a
+ e0 = eq (lit 42) (lit 21 +. lit 21)
+
+ print (PP p) = p
+ eval (Evaluator e) env = e env
+\end{lstlisting}
--- /dev/null
+A deep \gls{EDSL} is a language represented as an \gls{ADT}. Views are
+functions that transform something to the datatype or the other way around. As
+an example, take the simple arithmetic \gls{EDSL} shown in
+Listing~\ref{lst:exdeep}.
+
+\begin{lstlisting}[label={lst:exdeep},%
+ caption={A minimal deep \gls{EDSL}}]
+:: DSL
+ = LitI Int
+ | LitB Bool
+ | Var String
+ | Plus DSL DSL
+ | Minus DSL DSL
+ | And DSL DSL
+ | Eq DSL
+\end{lstlisting}
+
+Deep embedding has the advantage that it is easy to build and views
+are easy to add. To the downside, the expressions created with this language
+are not type-safe. In the given language it is possible to create an expression
+such as \CI{Plus (LitI 4) (LitB True)} that adds a boolean to an integer.
+Evermore so, extending the \gls{ADT} is easy and convenient but extending the
+views accordingly is tedious and has to be done individually for all views.
+
+The first downside of this type of \gls{EDSL} can be overcome by using
+\glspl{GADT}~\cite{cheney_first-class_2003}. Listing~\ref{lst:exdeepgadt} shows
+the same language, but type-safe with a \gls{GADT}. \glspl{GADT} are not
+supported in the current version of \gls{Clean} and therefore the syntax is
+hypothetical. However, it has been shown that \glspl{GADT} can be simulated
+using bimaps or projection pairs~\cite{cheney_lightweight_2002}. Unfortunately
+the lack of extendability remains a problem. If a language construct is added,
+no compile time guarantee is given that all views support it.
+
+\begin{lstlisting}[label={lst:exdeepgadt},%
+ caption={A minimal deep \gls{EDSL} using \glspl{GADT}}]
+:: DSL a
+ = LitI Int -> DSL Int
+ | LitB Bool -> DSL Bool
+ | E.e: Var String -> DSL e
+ | Plus (DSL Int) (DSL Int) -> DSL Int
+ | Minus (DSL Int) (DSL Int) -> DSL Int
+ | And (DSL Bool) (DSL Bool) -> DSL Bool
+ | E.e: Eq (DSL e) (DSL e) -> DSL Bool & == e
+\end{lstlisting}
--- /dev/null
+In a shallow \gls{EDSL} all language constructs are expressed as functions in
+the host language. An evaluator view for the example language then can be
+implemented as the code shown in Listing~\ref{lst:exshallow}. Note that much of
+the internals of the language can be hidden using monads.
+
+\begin{lstlisting}[label={lst:exshallow},%
+ caption={A minimal shallow \gls{EDSL}}]
+:: Env = ... // Some environment
+:: DSL a = DSL (Env -> a)
+
+Lit :: a -> DSL a
+Lit x = \e -> x
+
+Var :: String -> DSL Int
+Var i = \e -> retrEnv e i
+
+Plus :: (DSL Int) (DSL Int) -> DSL Int
+Plus x y = \e -> x e + y e
+
+...
+
+Eq :: (DSL a) (DSL a) -> DSL Bool | == a
+Eq x y = \e -> x e + y e
+\end{lstlisting}
+
+The advantage of shallowly embedding a language in a host language is its
+extendability. It is very easy to add functionality and compile time checks
+of the host language guarantee whether or not the functionality is available
+when used. Moreover, the language is type safe as it is directly typed in the
+host language.
+
+The downside of this method is extending the language with views. It is nearly
+impossible to add views to a shallowly embedded language. The only way of
+achieving this is by decorating the datatype for the \gls{EDSL} with all the
+information for all the views. This will mean that every component will have to
+implement all views rendering it slow for multiple views and complex to
+implement.
--- /dev/null
+An \gls{EDSL} is a language embedded in a host language. \glspl{EDSL} can have
+one or more backends or views. Commonly used views are pretty printing,
+compiling, simulating, verifying and proving the program. There are several
+techniques available for creating \glspl{EDSL}. They all have their own
+advantages and disadvantages in terms of extendability, typedness and view
+support. In the following subsections each of the main techniques are briefly
+explained.
+
+\section{Deep embedding}
+\input{edsl.deep}
+
+\section{Shallow embedding}
+\input{edsl.shallow}
+
+\section{Class based shallow embedding}
+\input{edsl.class}
--- /dev/null
+The structure of this thesis is as follows.
+
+Chapter~\ref{chp:introduction} contains the problem statement, motivation,
+related work and the structure of the document.
+Chapter~\ref{chp:top} introduces the reader to the basics of \gls{TOP} and
+\gls{iTasks}.
+Chapter~\ref{chp:dsl} discusses the pros and cons of different embedding
+methods to create \gls{EDSL}.
+Chapter~\ref{chp:mtask} shows the existing \gls{mTask}-\gls{EDSL} on which is
+extended upon in this dissertation.
+Chapter~\ref{chp:mtaskcont} describes the view and functionality for
+the \gls{mTask}-\gls{EDSL} that were added and used in the system.
+Chapter~\ref{chp:arch} shows the architecture used for \gls{IoT}-devices that
+are a part of the new \gls{mTask}-system. It covers the client software running
+on the device and the server written in \gls{iTasks}.
+Chapter~\ref{chp:conclusion} concludes by answering the research questions
+and discusses future research.
+Appendix~\ref{app:communication-protocol} shows the concrete protocol used for
+communicating between the server and client.
+Appendix~\ref{app:device-interface} shows the concrete interface for the
+devices.
+
+Text written using the \CI{Teletype} font indicates code and is often
+referring to a listing. \emph{Emphasized} text is used for proper nouns and
+words that have a unexpected meaning.
+
+The complete source code of this thesis can be found in the following git
+repository:\\
+\url{https://git.martlubbers.net/msc-thesis1617.git}
+
+The complete source code of the \gls{mTask}-system can be found in the
+following git repository:
+\url{https://git.martlubbers.net/mTask.git}
--- /dev/null
+\Gls{IoT} technology is emerging rapidly. It offers myriads of solutions
+and transforms the way we interact with technology.
+
+Initially the term was coined to describe \gls{RFID} devices and the
+communication between them. However, currently the term \gls{IoT} encompasses
+all small devices that communicate with each other and the world. These devices
+are often equipped with sensors, \gls{GNSS} modules\footnote{e.g.\ the American
+\gls{GPS} or the Russian \gls{GLONASS}.} and
+actuators~\cite{da_xu_internet_2014}. With these new technologies information
+can be tracked accurately using little power and bandwidth. Moreover, \gls{IoT}
+technology is coming into people's homes, clothes and
+healthcare~\cite{riazul_islam_internet_2015}. For example, for a few euros a
+consumer ready fitness tracker watch can be bought that tracks heartbeat and
+respiration levels.
+
+The \gls{TOP} paradigm and the corresponding \gls{iTasks} implementation offer
+a high abstraction level for real world workflow
+tasks~\cite{plasmeijer_itasks:_2007}. These workflow tasks can be described
+through an \gls{EDSL} and modeled as \glspl{Task}. The system will generate a
+multi-user web app from the specification. This web service can be accessed
+through a browser and is used to complete these \glspl{Task}. Familiar workflow
+patterns like sequential, parallel and conditional \glspl{Task} can be modelled
+using combinators.
+
+\gls{iTasks} has proven to be useful in many fields of operation such as
+incident management~\cite{lijnse_top_2013}. Interfaces are automatically
+generated for the types of data which makes rapid development possible.
+\Glspl{Task} in the \gls{iTasks} system are modelled after real life workflow
+tasks but the modelling is applied on a high level. Therefore it is difficult
+to connect \gls{iTasks}-\glspl{Task} to real world \glspl{Task} and allow them
+to interact. A lot of the actual tasks could be performed by small \gls{IoT}
+devices. Nevertheless, adding such devices to the current system is difficult
+to say the least as it was not designed to cope with these devices.
+
+In the current system such adapters connecting devices to \gls{iTasks} --- in
+principle --- can be written as \glspl{SDS}\footnote{Similar as to resources
+such as time are available in the current \gls{iTasks} implementation.}.
+However, this requires a very specific adapter to be written for every device
+and function. This forces a fixed logic in the device that is set at compile
+time. Many small \gls{IoT} devices have limited processing power but are still
+powerful enough for decision making. Recompiling the code for a small
+\gls{IoT} device is expensive and therefore it is difficult to use a device
+dynamically for multiple purposes. Oortgiese et al.\ lifted \gls{iTasks} from a
+single server model to a distributed server architecture that is also runnable
+on small devices such as those powered by
+\gls{ARM}~\cite{oortgiese_distributed_2017}. However, this is limited to
+fairly high performance devices that are equipped with high speed communication
+channels because it requires the device to run the entire \gls{iTasks} core.
+Devices in \gls{IoT} often have only Low Throughput Network communication with
+low bandwidth and a very limited amount of processing power and are therefore
+not suitable to run an entire \gls{iTasks} core.
--- /dev/null
+The updates to the \gls{mTask}-system~\cite{koopman_type-safe_nodate} will
+bridge this gap in the current system by introducing a new communication
+protocol, device application and \glspl{Task} synchronizing the two. The system
+can run on devices as small as \gls{Arduino}
+microcontrollers~\cite{noauthor_arduino_nodate} and operates via the same
+paradigms and patterns as regular \glspl{Task} in the \gls{TOP} paradigm.
+Devices in the \gls{mTask}-system can run small imperative programs written in
+an \gls{EDSL} and have access to \glspl{SDS}. \Glspl{Task} are sent to the
+device at runtime, avoiding recompilation and thus write cycles on the program
+memory.
--- /dev/null
+Similar research has been conducted on the subject.
+For example, microcontrollers such as the \gls{Arduino} can be remotely
+controlled by the \gls{Firmata}-protocol\footnote{``firmata/protocol:
+Documentation of the Firmata protocol.''
+(\url{https://github.com/firmata/protocol}). [Accessed: 23-May-2017].}. This
+protocol is designed to expose the peripherals such as sensors to the server.
+This allows very fine grained control but with the cost of excessive
+communication overhead since no code is executed on the device, only the
+peripherals are queried. A \gls{Haskell} implementation of the protocol is
+also available\footnote{``hArduino by LeventErkok.'' (\url{%
+https://leventerkok.github.io/hArduino}). [Accessed: 23-May-2017].}.
+
+\Gls{Clean} has a history of interpretation and there is a lot of research
+happening on the intermediate language \gls{SAPL}. \Gls{SAPL} is a purely
+functional intermediate language that has interpreters written in
+\gls{C++}~\cite{jansen_efficient_2007}, \gls{Javascript}%
+~\cite{domoszlai_implementing_2011} and \gls{Clean} and \gls{Haskell} compiler
+backends~\cite{domoszlai_compiling_2012}. However, interpreting the resulting
+code is still heap-heavy and therefore not directly suitable for devices with
+as little as $2K$ of RAM such as the \gls{Arduino} \emph{Uno}. It might be
+possible to compile the \gls{SAPL} code into efficient machine language or
+\gls{C} but then the system would lose its dynamic properties since the
+microcontroller then would have to be reprogrammed every time a new \gls{Task}
+is sent to the device.
+
+\Glspl{EDSL} have often been used to generate \gls{C} code for microcontroller
+environments. This work uses parts of the existing \gls{mTask}-\gls{EDSL} which
+generates \gls{C} code to run a \gls{TOP}-like system on microcontrollers%
+~\cite{plasmeijer_shallow_2016}~\cite{koopman_type-safe_nodate}. Again, this
+requires a reprogramming cycle every time the \gls{Task}-specification is
+changed.
+
+Another \gls{EDSL} designed to generate low-level high-assurance programs is
+called \gls{Ivory} and uses \gls{Haskell} as a host language%
+~\cite{elliott_guilt_2015}. The language uses the \gls{Haskell} type-system to
+make unsafe languages type safe. For example, \gls{Ivory} has been used in the
+automotive industry to program parts of an autopilot%
+~\cite{pike_programming_2014}~\cite{hickey_building_2014}. \Gls{Ivory}'s syntax
+is deeply embedded but the type system is shallowly embedded. This requires
+several \gls{Haskell} extensions that offer dependent type constructions. The
+process of compiling an \gls{Ivory} program happens in stages. The embedded
+code is transformed into an \gls{AST} that is sent to a backend. In the new
+system, the \gls{mTask}-\gls{EDSL} transforms the embedded code during
+compile-time directly into the backend which is often a state transformer that
+will execute on runtime.
--- /dev/null
+\section{Introduction}
+\input{intro.intro}
+
+\section{Problem statement}
+\input{intro.problem}
+
+\section{Document structure}
+\input{intro.doc}
+
+\section{Related work}
+\input{intro.related}
+++ /dev/null
-\section{Introduction}
-\Gls{IoT} technology is emerging rapidly. It offers myriads of solutions
-and transforms the way we interact with technology.
-
-Initially the term was coined to describe \gls{RFID} devices and the
-communication between them. However, currently the term \gls{IoT} encompasses
-all small devices that communicate with each other and the world. These devices
-are often equipped with sensors, \gls{GNSS} modules\footnote{e.g.\ the American
-\gls{GPS} or the Russian \gls{GLONASS}.} and
-actuators~\cite{da_xu_internet_2014}. With these new technologies information
-can be tracked accurately using little power and bandwidth. Moreover, \gls{IoT}
-technology is coming into people's homes, clothes and
-healthcare~\cite{riazul_islam_internet_2015}. For example, for a few euros a
-consumer ready fitness tracker watch can be bought that tracks heartbeat and
-respiration levels.
-
-The \gls{TOP} paradigm and the corresponding \gls{iTasks} implementation offer
-a high abstraction level for real world workflow
-tasks~\cite{plasmeijer_itasks:_2007}. These workflow tasks can be described
-through an \gls{EDSL} and modeled as \glspl{Task}. The system will generate a
-multi-user web app from the specification. This web service can be accessed
-through a browser and is used to complete these \glspl{Task}. Familiar workflow
-patterns like sequential, parallel and conditional \glspl{Task} can be modelled
-using combinators.
-
-\gls{iTasks} has proven to be useful in many fields of operation such as
-incident management~\cite{lijnse_top_2013}. Interfaces are automatically
-generated for the types of data which makes rapid development possible.
-\Glspl{Task} in the \gls{iTasks} system are modelled after real life workflow
-tasks but the modelling is applied on a high level. Therefore it is difficult
-to connect \gls{iTasks}-\glspl{Task} to real world \glspl{Task} and allow them
-to interact. A lot of the actual tasks could be performed by small \gls{IoT}
-devices. Nevertheless, adding such devices to the current system is difficult
-to say the least as it was not designed to cope with these devices.
-
-In the current system such adapters connecting devices to \gls{iTasks} --- in
-principle --- can be written as \glspl{SDS}\footnote{Similar as to resources
-such as time are available in the current \gls{iTasks} implementation.}.
-However, this requires a very specific adapter to be written for every device
-and function. This forces a fixed logic in the device that is set at compile
-time. Many small \gls{IoT} devices have limited processing power but are still
-powerful enough for decision making. Recompiling the code for a small
-\gls{IoT} device is expensive and therefore it is difficult to use a device
-dynamically for multiple purposes. Oortgiese et al.\ lifted \gls{iTasks} from a
-single server model to a distributed server architecture that is also runnable
-on small devices such as those powered by
-\gls{ARM}~\cite{oortgiese_distributed_2017}. However, this is limited to
-fairly high performance devices that are equipped with high speed communication
-channels because it requires the device to run the entire \gls{iTasks} core.
-Devices in \gls{IoT} often have only Low Throughput Network communication with
-low bandwidth and a very limited amount of processing power and are therefore
-not suitable to run an entire \gls{iTasks} core.
-
-\section{Problem statement}
-The updates to the \gls{mTask}-system~\cite{koopman_type-safe_nodate} will
-bridge this gap in the current system by introducing a new communication
-protocol, device application and \glspl{Task} synchronizing the two. The system
-can run on devices as small as \gls{Arduino}
-microcontrollers~\cite{noauthor_arduino_nodate} and operates via the same
-paradigms and patterns as regular \glspl{Task} in the \gls{TOP} paradigm.
-Devices in the \gls{mTask}-system can run small imperative programs written in
-an \gls{EDSL} and have access to \glspl{SDS}. \Glspl{Task} are sent to the
-device at runtime, avoiding recompilation and thus write cycles on the program
-memory.
-
-\section{Document structure}
-The structure of this thesis is as follows.
-
-Chapter~\ref{chp:introduction} contains the problem statement, motivation,
-related work and the structure of the document.
-Chapter~\ref{chp:top} introduces the reader to the basics of \gls{TOP} and
-\gls{iTasks}.
-Chapter~\ref{chp:dsl} discusses the pros and cons of different embedding
-methods to create \gls{EDSL}.
-Chapter~\ref{chp:mtask} shows the existing \gls{mTask}-\gls{EDSL} on which is
-extended upon in this dissertation.
-Chapter~\ref{chp:mtaskcont} describes the view and functionality for
-the \gls{mTask}-\gls{EDSL} that were added and used in the system.
-Chapter~\ref{chp:arch} shows the architecture used for \gls{IoT}-devices that
-are a part of the new \gls{mTask}-system. It covers the client software running
-on the device and the server written in \gls{iTasks}.
-Chapter~\ref{chp:conclusion} concludes by answering the research questions
-and discusses future research.
-Appendix~\ref{app:communication-protocol} shows the concrete protocol used for
-communicating between the server and client.
-Appendix~\ref{app:device-interface} shows the concrete interface for the
-devices.
-
-Text written using the \CI{Teletype} font indicates code and is often
-referring to a listing. \emph{Emphasized} text is used for proper nouns and
-words that have a unexpected meaning.
-
-The complete source code of this thesis can be found in the following git
-repository:\\
-\url{https://git.martlubbers.net/msc-thesis1617.git}
-
-The complete source code of the \gls{mTask}-system can be found in the
-following git repository:
-\url{https://git.martlubbers.net/mTask.git}
-
-\section{Related work}
-Similar research has been conducted on the subject.
-For example, microcontrollers such as the \gls{Arduino} can be remotely
-controlled by the \gls{Firmata}-protocol\footnote{``firmata/protocol:
-Documentation of the Firmata protocol.''
-(\url{https://github.com/firmata/protocol}). [Accessed: 23-May-2017].}. This
-protocol is designed to expose the peripherals such as sensors to the server.
-This allows very fine grained control but with the cost of excessive
-communication overhead since no code is executed on the device, only the
-peripherals are queried. A \gls{Haskell} implementation of the protocol is
-also available\footnote{``hArduino by LeventErkok.'' (\url{%
-https://leventerkok.github.io/hArduino}). [Accessed: 23-May-2017].}.
-
-\Gls{Clean} has a history of interpretation and there is a lot of research
-happening on the intermediate language \gls{SAPL}. \Gls{SAPL} is a purely
-functional intermediate language that has interpreters written in
-\gls{C++}~\cite{jansen_efficient_2007}, \gls{Javascript}%
-~\cite{domoszlai_implementing_2011} and \gls{Clean} and \gls{Haskell} compiler
-backends~\cite{domoszlai_compiling_2012}. However, interpreting the resulting
-code is still heap-heavy and therefore not directly suitable for devices with
-as little as $2K$ of RAM such as the \gls{Arduino} \emph{Uno}. It might be
-possible to compile the \gls{SAPL} code into efficient machine language or
-\gls{C} but then the system would lose its dynamic properties since the
-microcontroller then would have to be reprogrammed every time a new \gls{Task}
-is sent to the device.
-
-\Glspl{EDSL} have often been used to generate \gls{C} code for microcontroller
-environments. This work uses parts of the existing \gls{mTask}-\gls{EDSL} which
-generates \gls{C} code to run a \gls{TOP}-like system on microcontrollers%
-~\cite{plasmeijer_shallow_2016}~\cite{koopman_type-safe_nodate}. Again, this
-requires a reprogramming cycle every time the \gls{Task}-specification is
-changed.
-
-Another \gls{EDSL} designed to generate low-level high-assurance programs is
-called \gls{Ivory} and uses \gls{Haskell} as a host language%
-~\cite{elliott_guilt_2015}. The language uses the \gls{Haskell} type-system to
-make unsafe languages type safe. For example, \gls{Ivory} has been used in the
-automotive industry to program parts of an autopilot%
-~\cite{pike_programming_2014}~\cite{hickey_building_2014}. \Gls{Ivory}'s syntax
-is deeply embedded but the type system is shallowly embedded. This requires
-several \gls{Haskell} extensions that offer dependent type constructions. The
-process of compiling an \gls{Ivory} program happens in stages. The embedded
-code is transformed into an \gls{AST} that is sent to a backend. In the new
-system, the \gls{mTask}-\gls{EDSL} transforms the embedded code during
-compile-time directly into the backend which is often a state transformer that
-will execute on runtime.
+++ /dev/null
-An \gls{EDSL} is a language embedded in a host language. \glspl{EDSL} can have
-one or more backends or views. Commonly used views are pretty printing,
-compiling, simulating, verifying and proving the program. There are several
-techniques available for creating \glspl{EDSL}. They all have their own
-advantages and disadvantages in terms of extendability, typedness and view
-support. In the following subsections each of the main techniques are briefly
-explained.
-
-\section{Deep embedding}
-A deep \gls{EDSL} is a language represented as an \gls{ADT}. Views are
-functions that transform something to the datatype or the other way around. As
-an example, take the simple arithmetic \gls{EDSL} shown in
-Listing~\ref{lst:exdeep}.
-
-\begin{lstlisting}[label={lst:exdeep},%
- caption={A minimal deep \gls{EDSL}}]
-:: DSL
- = LitI Int
- | LitB Bool
- | Var String
- | Plus DSL DSL
- | Minus DSL DSL
- | And DSL DSL
- | Eq DSL
-\end{lstlisting}
-
-Deep embedding has the advantage that it is easy to build and views
-are easy to add. To the downside, the expressions created with this language
-are not type-safe. In the given language it is possible to create an expression
-such as \CI{Plus (LitI 4) (LitB True)} that adds a boolean to an integer.
-Evermore so, extending the \gls{ADT} is easy and convenient but extending the
-views accordingly is tedious and has to be done individually for all views.
-
-The first downside of this type of \gls{EDSL} can be overcome by using
-\glspl{GADT}~\cite{cheney_first-class_2003}. Listing~\ref{lst:exdeepgadt} shows
-the same language, but type-safe with a \gls{GADT}. \glspl{GADT} are not
-supported in the current version of \gls{Clean} and therefore the syntax is
-hypothetical. However, it has been shown that \glspl{GADT} can be simulated
-using bimaps or projection pairs~\cite{cheney_lightweight_2002}. Unfortunately
-the lack of extendability remains a problem. If a language construct is added,
-no compile time guarantee is given that all views support it.
-
-\begin{lstlisting}[label={lst:exdeepgadt},%
- caption={A minimal deep \gls{EDSL} using \glspl{GADT}}]
-:: DSL a
- = LitI Int -> DSL Int
- | LitB Bool -> DSL Bool
- | E.e: Var String -> DSL e
- | Plus (DSL Int) (DSL Int) -> DSL Int
- | Minus (DSL Int) (DSL Int) -> DSL Int
- | And (DSL Bool) (DSL Bool) -> DSL Bool
- | E.e: Eq (DSL e) (DSL e) -> DSL Bool & == e
-\end{lstlisting}
-
-\section{Shallow embedding}
-In a shallow \gls{EDSL} all language constructs are expressed as functions in
-the host language. An evaluator view for the example language then can be
-implemented as the code shown in Listing~\ref{lst:exshallow}. Note that much of
-the internals of the language can be hidden using monads.
-
-\begin{lstlisting}[label={lst:exshallow},%
- caption={A minimal shallow \gls{EDSL}}]
-:: Env = ... // Some environment
-:: DSL a = DSL (Env -> a)
-
-Lit :: a -> DSL a
-Lit x = \e -> x
-
-Var :: String -> DSL Int
-Var i = \e -> retrEnv e i
-
-Plus :: (DSL Int) (DSL Int) -> DSL Int
-Plus x y = \e -> x e + y e
-
-...
-
-Eq :: (DSL a) (DSL a) -> DSL Bool | == a
-Eq x y = \e -> x e + y e
-\end{lstlisting}
-
-The advantage of shallowly embedding a language in a host language is its
-extendability. It is very easy to add functionality and compile time checks
-of the host language guarantee whether or not the functionality is available
-when used. Moreover, the language is type safe as it is directly typed in the
-host language.
-
-The downside of this method is extending the language with views. It is nearly
-impossible to add views to a shallowly embedded language. The only way of
-achieving this is by decorating the datatype for the \gls{EDSL} with all the
-information for all the views. This will mean that every component will have to
-implement all views rendering it slow for multiple views and complex to
-implement.
-
-\section{Class based shallow embedding}
-The third type of embedding is called class-based shallow embedding and has the
-advantages of both shallow and deep
-embedding~\cite{svenningsson_combining_2012}. In class-based shallow embedding
-the language constructs are defined as type classes. This language is shown
-with the new method in Listing~\ref{lst:exclassshallow}.
-
-This type of embedding inherits the ease of adding views from shallow
-embedding. A view is just a different data type implementing one or more of the
-type classes as shown in the aforementioned Listing where an evaluator and a
-pretty printer are implemented.
-
-Just as with \glspl{GADT}, type safety is guaranteed in deep embedding. Type
-constraints are enforced through phantom types. One can add as many phantom
-types as necessary. Lastly, extensions can be added easily, just as in
-shallow embedding. When an extension is made in an existing class, all views
-must be updated accordingly to prevent possible runtime errors. When an
-extension is added in a new class, this problem does not arise and views can
-choose to implement only parts of the collection of classes.
-
-In contrast to deep embedding, it is very well possible to have multiple views
-applied on the same expression. This is also shown in the following listing.
-
-\begin{lstlisting}[label={lst:exclassshallow},%
- caption={A minimal class based shallow \gls{EDSL}}]
-:: Env = ... // Some environment
-:: Evaluator a = Evaluator (Env -> a)
-:: PrettyPrinter a = PP String
-
-class intArith where
- lit :: t -> v t | toString t
- add :: (v t) (v t) -> (v t) | + t
- minus :: (v t) (v t) -> (v t) | - t
-
-class boolArith where
- and :: (v Bool) (v Bool) -> (v Bool)
- eq :: (v t) (v t) -> (v Bool) | == t
-
-instance intArith Evaluator where
- lit x = \e->x
- add x y = ...
-
-instance intArith PrettyPrinter where
- lit x = toString x
- add x y = x +++ "+" +++ y
- ...
-
-...
-
-Start :: (PP String, Bool)
-Start = (print e0, eval e0)
-where
- e0 :: a Bool | intArith, boolArith a
- e0 = eq (lit 42) (lit 21 +. lit 21)
-
- print (PP p) = p
- eval (Evaluator e) env = e env
-\end{lstlisting}
+++ /dev/null
-The \gls{mTask}-\gls{EDSL} is the language used for the proposed system. The
-\gls{mTask}-\gls{EDSL} was created by Koopman et al.\ and supports several
-views such as an \gls{iTasks} simulation and a \gls{C}-code generator. The
-\gls{EDSL} was designed to generate a ready-to-compile \gls{TOP}-like program
-for microcontrollers such as the \gls{Arduino}~\cite{koopman_type-safe_nodate}%
-\cite{plasmeijer_shallow_2016}.
-
-The \gls{mTask}-\gls{EDSL} is a shallowly embedded class based \gls{EDSL} and
-therefore it is very suitable to have a new backend that partly implements the
-classes given. The following sections show the details of the \gls{EDSL} that
-is used in this extension. The parts of the \gls{EDSL} that are not used will
-not be discussed and the details of those parts can be found in the cited
-literature.
-
-A view for the \gls{mTask}-\gls{EDSL} is a type with two free type
-variables\footnote{kind \CI{*->*->*}.} that implements some of the classes
-given. The types do not have to be present as fields in the view and can, and
-will most often, be exclusively phantom types. Thus, views are of the
-form:\\\CI{:: v t r = ...}. The first type variable will be the type of the
-view. The second type variable will be the type of the \gls{EDSL}-expression
-and the third type variable represents the role of the expression. Currently
-the role of the expressions form a hierarchy. The three roles and their
-hierarchy are shown in Listing~\ref{lst:exprhier}. This implies that everything
-is a statement, only an \CI{Upd} and an \CI{Expr} are expressions. The \CI{Upd}
-restriction describes updatable expressions such as \gls{GPIO} pins and
-\glspl{SDS}.
-
-\begin{lstlisting}[%
- label={lst:exprhier},caption={Expression role hierarchy}]
-:: Upd = Upd
-:: Expr = Expr
-:: Stmt = Stmt
-
-class isExpr a :: a -> Int
-instance isExpr Upd
-instance isExpr Expr
-\end{lstlisting}
-
-\section{Expressions}
-Expressions in the \gls{mTask}-\gls{EDSL} are divided into two types, namely
-boolean expressions and arithmetic expressions. The class of arithmetic
-language constructs also contains the function \CI{lit} that lifts a
-host-language value into the \gls{EDSL} domain. All standard arithmetic
-functions are included in the \gls{EDSL} but are omitted in the example for
-brevity. Moreover, the class restrictions are only shown in the first functions
-and are omitted in subsequent functions. Both the boolean expression and
-arithmetic expression classes are shown in Listing~\ref{lst:arithbool}.
-
-\begin{lstlisting}[label={lst:arithbool},
- caption={Basic classes for expressions}]
-class arith v where
- lit :: t -> v t Expr
- (+.) infixl 6 :: (v t p) (v t q) -> v t Expr | +, zero t & isExpr p & isExpr q
- (-.) infixl 6 :: (v t p) (v t q) -> v t Expr | -, zero t & ...
- ...
-class boolExpr v where
- Not :: (v Bool p) -> v Bool Expr | ...
- (&.) infixr 3 :: (v Bool p) (v Bool q) -> v Bool Expr | ...
- ...
- (==.) infix 4 :: (v a p) (v a q) -> v Bool Expr | ==, toCode a & ...
-\end{lstlisting}
-
-\section{Control flow}
-Looping of \glspl{Task} happens because \glspl{Task} are executed after waiting
-a specified amount of time or when they are launched by another \gls{Task} or
-even themselves. Therefore there is no need for loop control flow functionality
-such as \emph{while} or \emph{for} constructions. The main control flow
-operators are the sequence operator and the \emph{if} statement. Both are shown
-in Listing~\ref{lst:control}. The first class of \emph{If} statements describes
-the regular \emph{if} statement. The expressions given can have any role. The
-functional dependency on \CI{s} determines the return type of the statement.
-The listing includes examples of implementations that illustrate this
-dependency. A special \emph{If} statement --- only used for statements --- is
-also added under the name \CI{IF}, of which the \CI{?} is a conditional
-statement to execute.
-
-The sequence operator is straightforward and its only function is to tie
-two expressions together. The left expression is executed first, followed by
-the right expression.
-
-\begin{lstlisting}[%
- label={lst:control},caption={Control flow operators}]
-class If v q r ~s where
- If :: (v Bool p) (v t q) (v t r) -> v t s | ...
-
-class IF v where
- IF :: (v Bool p) (v t q) (v s r) -> v () Stmt | ...
- (?) infix 1 :: (v Bool p) (v t q) -> v () Stmt | ...
-
-instance If Code Stmt Stmt Stmt
-instance If Code e Stmt Stmt
-instance If Code Stmt e Stmt
-instance If Code x y Expr
-
-class seq v where
- (:.) infixr 0 :: (v t p) (v u q) -> v u Stmt | ...
-\end{lstlisting}
-
-\section{Input/Output and class extensions}
-Values can be assigned to all expressions that have an \CI{Upd} role. Examples
-of such expressions are \glspl{SDS} and \gls{GPIO} pins. Moreover, class
-extensions can be created for specific peripherals such as built-in
-\glspl{LED}. The classes facilitating this are shown in
-Listing~\ref{lst:sdsio}. In this way the assignment is the same for every
-assignable entity.
-
-\begin{lstlisting}[%
- label={lst:sdsio},caption={Input/Output classes}]
-:: DigitalPin = D0 | D1 | D2 | D3 | D4 | D5 |D6 | D7 | D8 | D9 | D10 | D11 | D12 | D13
-:: AnalogPin = A0 | A1 | A2 | A3 | A4 | A5
-:: UserLED = LED1 | LED2 | LED3
-
-class dIO v where dIO :: DigitalPin -> v Bool Upd
-class aIO v where aIO :: AnalogPin -> v Int Upd
-class analogRead v where
- analogRead :: AnalogPin -> v Int Expr
- analogWrite :: AnalogPin (v Int p) -> v Int Expr
-class digitalRead v where
- digitalRead :: DigitalPin -> v Bin Expr
- digitalWrite :: DigitalPin (v Bool p) -> v Int Expr
-
-:: UserLED = LED1 | LED2 | LED3
-class userLed v where
- ledOn :: (v UserLED q) -> (v () Stmt)
- ledOff :: (v UserLED q) -> (v () Stmt)
-
-class assign v where
- (=.) infixr 2 :: (v t Upd) (v t p) -> v t Expr | ...
-\end{lstlisting}
-
-One way of storing data in \gls{mTask}-\glspl{Task} is using \glspl{SDS}.
-\glspl{SDS} serve as variables in \gls{mTask} and maintain their value across
-executions. \glspl{SDS} can be used by multiple \glspl{Task} and can be used
-to share data. The classes associated with \glspl{SDS} are listed in
-Listing~\ref{lst:sdsclass}. The \CI{Main} type is introduced to box an
-\gls{mTask} and make it recognizable by the type system by separating programs
-and decorations such as \glspl{SDS}.
-
-\begin{lstlisting}[%
- label={lst:sdsclass},caption={\glspl{SDS} in \gls{mTask}}]
-:: In a b = In infix 0 a b
-:: Main a = {main :: a}
-
-class sds v where
- sds :: ((v t Upd)->In t (Main (v c s))) -> (Main (v c s)) | ...
-\end{lstlisting}
-
-\section{Semantics}
-The \gls{C}-backend of the \gls{mTask}-system has an engine that is generated
-alongside the code for the \glspl{Task}. This engine will execute the
-\gls{mTask}-\glspl{Task} according to certain rules and semantics.
-\gls{mTask}-\glspl{Task} do not behave like functions but more like
-\gls{iTasks}-\glspl{Task}. An \gls{mTask} is queued when either its timer runs
-out or when it is launched by another \gls{mTask}. When an \gls{mTask} is
-queued it does not block the execution and it will return immediately while the
-actual \gls{Task} will be executed anytime in the future.
-
-The \gls{iTasks}-backend simulates the \gls{C}-backend and thus uses the same
-semantics. This engine expressed in pseudocode is listed as
-Algorithm~\ref{lst:engine}. All the \glspl{Task} are inspected on their waiting
-time. When the waiting time has not passed; the delta is subtracted and the
-\gls{Task} gets pushed to the end of the queue. When the waiting has surpassed
-they are executed. When an \gls{mTask} opts to queue another \gls{mTask} it
-can just append it to the queue.
-
-~\\
-\begin{algorithm}[H]
- \KwData{\textbf{queue} queue, \textbf{time} $t, t_p$}
-
- $t\leftarrow\text{now}()$\;
- \Begin{
- \While{true}{
- $t_p\leftarrow t$\;
- $t\leftarrow\text{now}()$\;
- \If{notEmpty$($queue$)$}{
- $task\leftarrow \text{queue.pop}()$\;
- $task$.wait $\leftarrow task$.wait $-(t-t_p)$\;
- \eIf{$task.wait>t_0$}{
- queue.append$(task)$\;
- }{
- run\_task$(task)$\;
- }
- }
- }
- }
- \caption{Engine pseudocode for the \gls{C}- and
- \gls{iTasks}-view}\label{lst:engine}
-\end{algorithm}
-~\\
-
-To achieve this in the \gls{EDSL} a \gls{Task} class is added that work in a
-similar fashion as the \texttt{sds} class. This class is listed in
-Listing~\ref{lst:taskclass}. \glspl{Task} can have an argument and always have
-to specify a delay or waiting time. The type signature of the \CI{mtask} is
-complex and therefore an example is given. The aforementioned Listing
-shows a simple specification containing one \gls{Task} that increments a value
-indefinitely every one seconds.
-
-\begin{lstlisting}[label={lst:taskclass},%
- caption={The classes for defining \glspl{Task}}]
-class mtask v a where
- task :: (((v delay r) a->v MTask Expr)->In (a->v u p) (Main (v t q))) -> Main (v t q) | ...
-
-count = task \count = (\n.count (lit 1000) (n +. One)) In {main = count (lit 1000) Zero}
-\end{lstlisting}
-
-\section{Example mTask}
-Some example \gls{mTask}-\glspl{Task} using almost all of their functionality
-are shown in Listing~\ref{lst:exmtask}. The \gls{mTask}-\glspl{Task} shown in
-the example do not belong to a particular view and therefore are of the type
-\CI{View t r}. The \CI{blink} \gls{mTask} show the classic \gls{Arduino}
-blinking led application that blinks a certain \gls{LED} every second. The
-\CI{thermostat} expression will enable a digital pin powering a cooling fan
-when the analog pin representing a temperature sensor is too high.
-\CI{thermostat`} shows the same expression but now using the assignment style
-\gls{GPIO} technique. The \CI{thermostat} example also shows that it is not
-necessary to run everything as a \CI{task}. The main program code can also just
-consist of the contents of the root \CI{main} itself.
-
-\begin{lstlisting}[%
- label={lst:exmtask},caption={Some example \gls{mTask}-\glspl{Task}}]
-blink = task \blink=(\x.
- IF (x ==. lit True) (ledOn led) (ledOff led) :.
- blink (lit 1000) (Not x)
- In {main=blink (lit 1000) True}
-
-thermostat :: Main (View () Stmt)
-thermostat = {main =
- IF (analogRead A0 >. lit 50)
- ( digitalWrite D0 (lit True) )
- ( digitalWrite D0 (lit False) )
- }
-
-thermostat` :: Main (View () Stmt)
-thermostat` = let
- a0 = aIO A0
- d0 = dIO D0 in {main = IF (a0 >. lit 50) (d0 =. lit True) (d0 =. lit False) }
-\end{lstlisting}
+++ /dev/null
-\section{iTasks}
-\gls{TOP} is a novel programming paradigm implemented as
-\gls{iTasks}~\cite{achten_introduction_2015} in the pure lazy functional
-language \gls{Clean}~\cite{brus_cleanlanguage_1987}. \gls{iTasks} is an
-\gls{EDSL} to model workflow tasks in the broadest sense. A \gls{Task} is just
-a function that --- given some state --- returns the observable \CI{TaskValue}.
-The \CI{TaskValue} of a \CI{Task} can have different states. Not all state
-transitions are possible as shown in Figure~\ref{fig:taskvalue}. Once a value
-is stable it can never become unstable again. Stability is often reached by
-pressing a confirmation button. \glspl{Task} yielding a constant value are
-immediately stable.
-
-A simple \gls{iTasks} example illustrating the route to stability of a
-\gls{Task} in which the user has to enter a full name is shown in
-Listing~\ref{lst:taskex}. The code is accompanied by screenshots showing the
-user interface in Figure~\ref{fig:taskex1},~\ref{fig:taskex2}
-and~\ref{fig:taskex3}. The \CI{TaskValue} of the \gls{Task} is in the first
-image in the \CI{NoValue} state, the second image does not have all the fields
-filled in and therefore the \CI{TaskValue} remains \CI{NoValue}. In the third
-image all fields are entered and the \CI{TaskValue} transitions to the
-\CI{Unstable} state. When the user presses \emph{Continue} the value becomes
-\CI{Stable} and cannot be changed any further.
-
-\begin{figure}[H]
- \centering
- \includegraphics[width=.5\linewidth]{fig-taskvalue}
- \caption{The states of a \CI{TaskValue}}\label{fig:taskvalue}
-\end{figure}
-
-\begin{lstlisting}[label={lst:taskex},%
- caption={An example \gls{Task} for entering a name}]
-:: Name = { firstname :: String
- , lastname :: String
- }
-
-derive class iTask Name
-
-enterInformation :: String [EnterOption m] -> (Task m) | iTask m
-
-enterName :: Task Name
-enterName = enterInformation "Enter your name" []
-\end{lstlisting}
-
-\begin{figure}[H]
- \centering
- \begin{subfigure}{.25\textwidth}
- \centering
- \includegraphics[width=.9\linewidth]{taskex1}
- \caption{Initial interface}\label{fig:taskex1}
- \end{subfigure}
- \begin{subfigure}{.25\textwidth}
- \centering
- \includegraphics[width=.9\linewidth]{taskex2}
- \caption{Incomplete entrance}\label{fig:taskex2}
- \end{subfigure}
- \begin{subfigure}{.25\textwidth}
- \centering
- \includegraphics[width=.9\linewidth]{taskex3}
- \caption{Complete entry}\label{fig:taskex3}
- \end{subfigure}
- \caption{Example of a generated user interface}
-\end{figure}
-
-For a type to be suitable, it must have instances for a collection of generic
-functions that is captured in the class \CI{iTask}. Basic types have
-specialization instances for these functions and show an interface accordingly.
-Derived interfaces can be modified with decoration operators or specializations
-can be created.
-
-\section{Combinators}
-\Glspl{Task} can be combined using so called \gls{Task}-combinators.
-Combinators describe relations between \glspl{Task}. There are only two basic
-types of combinators; parallel and sequence. All other combinators are
-derived from the basic combinators. Type signatures of simplified versions of
-the basic combinators and their derivations are given in
-Listing~\ref{lst:combinators}
-
-\begin{lstlisting}[%
- caption={\Gls{Task}-combinators},label={lst:combinators}]
-//Step combinator
-(>>=) infixl 1 :: (Task a) (a -> Task b) -> Task b | iTask a & iTask b
-(>>*) infixl 1 :: (Task a) [TaskCont a (Task b)] -> Task b | iTask a & iTask b
-:: TaskCont a b
- = OnValue ((TaskValue a) -> Maybe b)
- | OnAction Action ((TaskValue a) -> Maybe b)
- | E.e: OnException (e -> b) & iTask e
- | OnAllExceptions (String -> b)
-:: Action = Action String
-
-//Parallel combinators
-(-||-) infixr 3 :: (Task a) (Task a) -> Task a | iTask a
-(||-) infixr 3 :: (Task a) (Task b) -> Task b | iTask a & iTask b
-(-||) infixl 3 :: (Task a) (Task b) -> Task a | iTask a & iTask b
-(-&&-) infixr 4 :: (Task a) (Task b) -> Task (a,b) | iTask a & iTask b
-\end{lstlisting}
-
-\paragraph{Sequence:}
-The implementation for the sequence combinator is called the
-\CI{step} (\CI{>>*}). This combinator runs the left-hand \gls{Task} and
-starts the right-hand side when a certain predicate holds. Predicates
-can be propositions about the \CI{TaskValue}, user actions from within
-the web browser or a thrown exception. The familiar
-bind-combinator is an example of a sequence combinator. This combinator
-runs the left-hand side and continues to the right-hand \gls{Task} if
-there is an \CI{UnStable} value and the user presses continue or when
-the value is \CI{Stable}. The combinator could have been implemented
-as follows:
-\begin{lstlisting}[language=Clean]
-(>>=) infixl 1 :: (Task a) (a -> (Task b)) -> (Task b) | iTask a & iTask b
-(>>=) ta f = ta >>* [OnAction "Continue" onValue, OnValue onStable]
- where
- onValue (Value a _) = Just (f a)
- onValue _ = Nothing
-
- onStable (Value a True) = Just (f a)
- onStable _ = Nothing
-\end{lstlisting}
-
-\paragraph{Parallel:}
-The parallel combinator allows for concurrent \glspl{Task}. The
-\glspl{Task} combined with these operators will appear at the same time
-in the web browser of the user and the results are combined as the type
-dictates. All parallel combinators used are derived from the basic parallel
-combinator that is very complex and only used internally.
-
-\section{Shared Data Sources}
-\Glspl{SDS} are an abstraction over resources that are available in the world
-or in the \gls{iTasks} system. The shared data can be a file on disk, the
-system time, a random integer or just some data stored in memory. The actual
-\gls{SDS} is just a record containing functions on how to read and write the
-source. In these functions the \CI{*IWorld} --- which in turn contains the real
-\CI{*World} --- is available. Accessing the outside world is required for
-interacting with it and thus the functions can access files on disk, raw
-memory, other \glspl{SDS} and hardware.
-
-The basic operations for \glspl{SDS} are get, set and update. The signatures
-for these functions are shown in Listing~\ref{lst:shares}. By default, all
-\glspl{SDS} are files containing a \gls{JSON} encoded version of the object and
-thus are persistent between restarts of the program. Library functions for
-shares residing in memory are available as well. The three main operations on
-shares are atomic in the sense that during reading no other \glspl{Task} are
-executed. The system provides useful functions to transform, map and combine
-\glspl{SDS} using combinators. The system also provides functionality to
-inspect the value of an \gls{SDS} and act upon a change. \Glspl{Task} waiting on
-an \gls{SDS} to change are notified when needed. This results in low resource
-usage because \glspl{Task} are never constantly inspecting \gls{SDS} values but
-are notified.
-
-\begin{lstlisting}[%
- label={lst:shares},caption={\Gls{SDS} functions}]
-:: RWShared p r w = ...
-:: ReadWriteShared r w :== RWShared () r w
-:: ROShared p r :== RWShared p () r
-:: ReadOnlyShared r :== ROShared () r
-
-:: Shared r :== ReadWriteShared r r
-
-get :: (ReadWriteShared r w) -> Task r | iTask r
-set :: w (ReadWriteShared r w) -> Task w | iTask w
-upd :: (r -> w) (ReadWriteShared r w) -> Task w | iTask r & iTask w
-
-sharedStore :: String a -> Shared a | JSONEncode{|*|}, JSONDecode{|*|}
-\end{lstlisting}
-
-\section{Parametric Lenses}
-\Glspl{SDS} can contain complex data structures such as lists, trees and even
-resources in the outside world. Sometimes, an update action only updates a part
-of the resource. When this happens, all waiting \glspl{Task} looking at the
-resource are notified of the update. However, it may be the case that
-\glspl{Task} were only looking at parts of the structure that was not updated.
-To solve this problem, parametric lenses were
-introduced~\cite{domoszlai_parametric_2014}.
-
-Parametric lenses add a type variable to the \gls{SDS}. This type variable is
-fixed to the void type (i.e. \CI{()}) in the given functions. When an \gls{SDS}
-executes a write operation, it also provides the system with a notification
-predicate. This notification predicate is a function \CI{p -> Bool} where
-\CI{p} is the parametric lens type. This allows programmers to create a big
-\gls{SDS}, and have \glspl{Task} only look at parts of the big \gls{SDS}. This
-technique is used in the current system in memory shares. The \CI{IWorld}
-contains a map that is accessible through an \gls{SDS}. While all data is
-stored in the map, only \glspl{Task} looking at a specific entry are notified
-when the structure is updated. The type of the parametric lens is the key in
-the map.
-
-Functionality for setting parameters is available in the system. The most
-important functions are the \CI{sdsFocus} and the \CI{sdsLens} function. These
-functions are listed in Listing~\ref{lst:focus}. \CI{sdsFocus} allows the
-programmer to fix a parametric lens value. \CI{sdsLens} is a kind of
-\CI{mapReadWrite} including access to the parametric lens value. This allows
-the creation of, for example, \glspl{SDS} that only read and write to parts of
-the original \gls{SDS}.
-
-\begin{lstlisting}[label={lst:focus},
- caption={Parametric lens functions}]
-sdsFocus :: p (RWShared p r w) -> RWShared p` r w | iTask p
-
-:: SDSNotifyPred p :== p -> Bool
-
-:: SDSLensRead p r rs = SDSRead (p -> rs -> MaybeError TaskException r)
- | SDSReadConst (p -> r)
-:: SDSLensWrite p w rs ws = SDSWrite (p -> rs -> w -> MaybeError TaskException (Maybe ws))
- | SDSWriteConst (p -> w -> MaybeError TaskException (Maybe ws))
-:: SDSLensNotify p w rs = SDSNotify (p -> rs -> w -> SDSNotifyPred p)
- | SDSNotifyConst (p -> w -> SDSNotifyPred p)
-
-sdsLens :: String (p -> ps) (SDSLensRead p r rs) (SDSLensWrite p w rs ws) (SDSLensNotify p w rs)
- (RWShared ps rs ws) -> RWShared p r w | iTask ps
-\end{lstlisting}
--- /dev/null
+Looping of \glspl{Task} happens because \glspl{Task} are executed after waiting
+a specified amount of time or when they are launched by another \gls{Task} or
+even themselves. Therefore there is no need for loop control flow functionality
+such as \emph{while} or \emph{for} constructions. The main control flow
+operators are the sequence operator and the \emph{if} statement. Both are shown
+in Listing~\ref{lst:control}. The first class of \emph{If} statements describes
+the regular \emph{if} statement. The expressions given can have any role. The
+functional dependency on \CI{s} determines the return type of the statement.
+The listing includes examples of implementations that illustrate this
+dependency. A special \emph{If} statement --- only used for statements --- is
+also added under the name \CI{IF}, of which the \CI{?} is a conditional
+statement to execute.
+
+The sequence operator is straightforward and its only function is to tie
+two expressions together. The left expression is executed first, followed by
+the right expression.
+
+\begin{lstlisting}[%
+ label={lst:control},caption={Control flow operators}]
+class If v q r ~s where
+ If :: (v Bool p) (v t q) (v t r) -> v t s | ...
+
+class IF v where
+ IF :: (v Bool p) (v t q) (v s r) -> v () Stmt | ...
+ (?) infix 1 :: (v Bool p) (v t q) -> v () Stmt | ...
+
+instance If Code Stmt Stmt Stmt
+instance If Code e Stmt Stmt
+instance If Code Stmt e Stmt
+instance If Code x y Expr
+
+class seq v where
+ (:.) infixr 0 :: (v t p) (v u q) -> v u Stmt | ...
+\end{lstlisting}
--- /dev/null
+Some example \gls{mTask}-\glspl{Task} using almost all of their functionality
+are shown in Listing~\ref{lst:exmtask}. The \gls{mTask}-\glspl{Task} shown in
+the example do not belong to a particular view and therefore are of the type
+\CI{View t r}. The \CI{blink} \gls{mTask} show the classic \gls{Arduino}
+blinking led application that blinks a certain \gls{LED} every second. The
+\CI{thermostat} expression will enable a digital pin powering a cooling fan
+when the analog pin representing a temperature sensor is too high.
+\CI{thermostat`} shows the same expression but now using the assignment style
+\gls{GPIO} technique. The \CI{thermostat} example also shows that it is not
+necessary to run everything as a \CI{task}. The main program code can also just
+consist of the contents of the root \CI{main} itself.
+
+\begin{lstlisting}[%
+ label={lst:exmtask},caption={Some example \gls{mTask}-\glspl{Task}}]
+blink = task \blink=(\x.
+ IF (x ==. lit True) (ledOn led) (ledOff led) :.
+ blink (lit 1000) (Not x)
+ In {main=blink (lit 1000) True}
+
+thermostat :: Main (View () Stmt)
+thermostat = {main =
+ IF (analogRead A0 >. lit 50)
+ ( digitalWrite D0 (lit True) )
+ ( digitalWrite D0 (lit False) )
+ }
+
+thermostat` :: Main (View () Stmt)
+thermostat` = let
+ a0 = aIO A0
+ d0 = dIO D0 in {main = IF (a0 >. lit 50) (d0 =. lit True) (d0 =. lit False) }
+\end{lstlisting}
--- /dev/null
+Expressions in the \gls{mTask}-\gls{EDSL} are divided into two types, namely
+boolean expressions and arithmetic expressions. The class of arithmetic
+language constructs also contains the function \CI{lit} that lifts a
+host-language value into the \gls{EDSL} domain. All standard arithmetic
+functions are included in the \gls{EDSL} but are omitted in the example for
+brevity. Moreover, the class restrictions are only shown in the first functions
+and are omitted in subsequent functions. Both the boolean expression and
+arithmetic expression classes are shown in Listing~\ref{lst:arithbool}.
+
+\begin{lstlisting}[label={lst:arithbool},
+ caption={Basic classes for expressions}]
+class arith v where
+ lit :: t -> v t Expr
+ (+.) infixl 6 :: (v t p) (v t q) -> v t Expr | +, zero t & isExpr p & isExpr q
+ (-.) infixl 6 :: (v t p) (v t q) -> v t Expr | -, zero t & ...
+ ...
+class boolExpr v where
+ Not :: (v Bool p) -> v Bool Expr | ...
+ (&.) infixr 3 :: (v Bool p) (v Bool q) -> v Bool Expr | ...
+ ...
+ (==.) infix 4 :: (v a p) (v a q) -> v Bool Expr | ==, toCode a & ...
+\end{lstlisting}
--- /dev/null
+Values can be assigned to all expressions that have an \CI{Upd} role. Examples
+of such expressions are \glspl{SDS} and \gls{GPIO} pins. Moreover, class
+extensions can be created for specific peripherals such as built-in
+\glspl{LED}. The classes facilitating this are shown in
+Listing~\ref{lst:sdsio}. In this way the assignment is the same for every
+assignable entity.
+
+\begin{lstlisting}[%
+ label={lst:sdsio},caption={Input/Output classes}]
+:: DigitalPin = D0 | D1 | D2 | D3 | D4 | D5 |D6 | D7 | D8 | D9 | D10 | D11 | D12 | D13
+:: AnalogPin = A0 | A1 | A2 | A3 | A4 | A5
+:: UserLED = LED1 | LED2 | LED3
+
+class dIO v where dIO :: DigitalPin -> v Bool Upd
+class aIO v where aIO :: AnalogPin -> v Int Upd
+class analogRead v where
+ analogRead :: AnalogPin -> v Int Expr
+ analogWrite :: AnalogPin (v Int p) -> v Int Expr
+class digitalRead v where
+ digitalRead :: DigitalPin -> v Bin Expr
+ digitalWrite :: DigitalPin (v Bool p) -> v Int Expr
+
+:: UserLED = LED1 | LED2 | LED3
+class userLed v where
+ ledOn :: (v UserLED q) -> (v () Stmt)
+ ledOff :: (v UserLED q) -> (v () Stmt)
+
+class assign v where
+ (=.) infixr 2 :: (v t Upd) (v t p) -> v t Expr | ...
+\end{lstlisting}
+
+One way of storing data in \gls{mTask}-\glspl{Task} is using \glspl{SDS}.
+\glspl{SDS} serve as variables in \gls{mTask} and maintain their value across
+executions. \glspl{SDS} can be used by multiple \glspl{Task} and can be used
+to share data. The classes associated with \glspl{SDS} are listed in
+Listing~\ref{lst:sdsclass}. The \CI{Main} type is introduced to box an
+\gls{mTask} and make it recognizable by the type system by separating programs
+and decorations such as \glspl{SDS}.
+
+\begin{lstlisting}[%
+ label={lst:sdsclass},caption={\glspl{SDS} in \gls{mTask}}]
+:: In a b = In infix 0 a b
+:: Main a = {main :: a}
+
+class sds v where
+ sds :: ((v t Upd)->In t (Main (v c s))) -> (Main (v c s)) | ...
+\end{lstlisting}
--- /dev/null
+The \gls{C}-backend of the \gls{mTask}-system has an engine that is generated
+alongside the code for the \glspl{Task}. This engine will execute the
+\gls{mTask}-\glspl{Task} according to certain rules and semantics.
+\gls{mTask}-\glspl{Task} do not behave like functions but more like
+\gls{iTasks}-\glspl{Task}. An \gls{mTask} is queued when either its timer runs
+out or when it is launched by another \gls{mTask}. When an \gls{mTask} is
+queued it does not block the execution and it will return immediately while the
+actual \gls{Task} will be executed anytime in the future.
+
+The \gls{iTasks}-backend simulates the \gls{C}-backend and thus uses the same
+semantics. This engine expressed in pseudocode is listed as
+Algorithm~\ref{lst:engine}. All the \glspl{Task} are inspected on their waiting
+time. When the waiting time has not passed; the delta is subtracted and the
+\gls{Task} gets pushed to the end of the queue. When the waiting has surpassed
+they are executed. When an \gls{mTask} opts to queue another \gls{mTask} it
+can just append it to the queue.
+
+~\\
+\begin{algorithm}[H]
+ \KwData{\textbf{queue} queue, \textbf{time} $t, t_p$}
+
+ $t\leftarrow\text{now}()$\;
+ \Begin{
+ \While{true}{
+ $t_p\leftarrow t$\;
+ $t\leftarrow\text{now}()$\;
+ \If{notEmpty$($queue$)$}{
+ $task\leftarrow \text{queue.pop}()$\;
+ $task$.wait $\leftarrow task$.wait $-(t-t_p)$\;
+ \eIf{$task.wait>t_0$}{
+ queue.append$(task)$\;
+ }{
+ run\_task$(task)$\;
+ }
+ }
+ }
+ }
+ \caption{Engine pseudocode for the \gls{C}- and
+ \gls{iTasks}-view}\label{lst:engine}
+\end{algorithm}
+~\\
+
+To achieve this in the \gls{EDSL} a \gls{Task} class is added that work in a
+similar fashion as the \texttt{sds} class. This class is listed in
+Listing~\ref{lst:taskclass}. \glspl{Task} can have an argument and always have
+to specify a delay or waiting time. The type signature of the \CI{mtask} is
+complex and therefore an example is given. The aforementioned Listing
+shows a simple specification containing one \gls{Task} that increments a value
+indefinitely every one seconds.
+
+\begin{lstlisting}[label={lst:taskclass},%
+ caption={The classes for defining \glspl{Task}}]
+class mtask v a where
+ task :: (((v delay r) a->v MTask Expr)->In (a->v u p) (Main (v t q))) -> Main (v t q) | ...
+
+count = task \count = (\n.count (lit 1000) (n +. One)) In {main = count (lit 1000) Zero}
+\end{lstlisting}
--- /dev/null
+The \gls{mTask}-\gls{EDSL} is the language used for the proposed system. The
+\gls{mTask}-\gls{EDSL} was created by Koopman et al.\ and supports several
+views such as an \gls{iTasks} simulation and a \gls{C}-code generator. The
+\gls{EDSL} was designed to generate a ready-to-compile \gls{TOP}-like program
+for microcontrollers such as the \gls{Arduino}~\cite{koopman_type-safe_nodate}%
+\cite{plasmeijer_shallow_2016}.
+
+The \gls{mTask}-\gls{EDSL} is a shallowly embedded class based \gls{EDSL} and
+therefore it is very suitable to have a new backend that partly implements the
+classes given. The following sections show the details of the \gls{EDSL} that
+is used in this extension. The parts of the \gls{EDSL} that are not used will
+not be discussed and the details of those parts can be found in the cited
+literature.
+
+A view for the \gls{mTask}-\gls{EDSL} is a type with two free type
+variables\footnote{kind \CI{*->*->*}.} that implements some of the classes
+given. The types do not have to be present as fields in the view and can, and
+will most often, be exclusively phantom types. Thus, views are of the
+form:\\\CI{:: v t r = ...}. The first type variable will be the type of the
+view. The second type variable will be the type of the \gls{EDSL}-expression
+and the third type variable represents the role of the expression. Currently
+the role of the expressions form a hierarchy. The three roles and their
+hierarchy are shown in Listing~\ref{lst:exprhier}. This implies that everything
+is a statement, only an \CI{Upd} and an \CI{Expr} are expressions. The \CI{Upd}
+restriction describes updatable expressions such as \gls{GPIO} pins and
+\glspl{SDS}.
+
+\begin{lstlisting}[%
+ label={lst:exprhier},caption={Expression role hierarchy}]
+:: Upd = Upd
+:: Expr = Expr
+:: Stmt = Stmt
+
+class isExpr a :: a -> Int
+instance isExpr Upd
+instance isExpr Expr
+\end{lstlisting}
+
+\section{Expressions}
+\input{mtask.expr}
+
+\section{Control flow}
+\input{mtask.control}
+
+\section{Input/Output and class extensions}
+\input{mtask.io}
+
+\section{Semantics}
+\input{mtask.semantics}
+
+\section{Example mTask}
+\input{mtask.examples}
-The \glspl{Task} suitable for a client are called \gls{mTask}-\gls{Task} and
-are written in the aforementioned \gls{mTask}-\gls{EDSL}. Some functionality of
-the original \gls{mTask}-\gls{EDSL} will not be used in this system.
-Conversely, some functionality needed was not available in the existing
-\gls{EDSL}. Due to the nature of class based shallow embedding this obstacle is
-easy to solve. A type --- housing the \gls{EDSL} --- does not have to implement
-all the available classes. Moreover, classes can be added at will without
-interfering with the existing views.
-
-\section{\gls{Task} Semantics}
-The current \gls{mTask} engine for devices does not support \glspl{Task} in the
-sense that the \gls{C}-view does. \Glspl{Task} used with the \gls{C}-view are a
-main program that executes code and launches \glspl{Task}. It was also possible
-to just have a main program. The current \gls{mTask}-system only supports main
-programs. Sending a \gls{Task} always goes together with choosing a scheduling
-strategy. This strategy can be one of the following three strategies as
-reflected in the \CI{MTTask} message type.
-
-\begin{itemize}
- \item\CI{OneShot}
-
- \CI{OneShot} takes no parameters and means that the \gls{Task} will run
- once and will then be removed automatically. This type of scheduling
- could be useful, for example, in retrieving sensor information on
- request of a user.
- \item\CI{OnInterval}
-
- \CI{OnInterval} has the number of milliseconds to wait in between
- executions as a parameter. \Glspl{Task} running with this scheduling
- method are executed at predetermined intervals.
- \item\CI{OnInterrupt}
-
- The last scheduling method is running \glspl{Task} on a specific
- interrupt. Unfortunatly, due to time constraints and focus, none of the
- current client implementations support this. Interrupt scheduling is
- useful for \glspl{Task} that have to react on a certain type of
- hardware event such as the press of a button.
-\end{itemize}
-
-\section{\gls{SDS} semantics}
-\Gls{mTask}-\glspl{SDS} on a client are available on the server as in the form
-of regular \gls{iTasks}-\glspl{SDS}. However, the same freedom that an
-\gls{SDS} has in the \gls{iTasks}-system is not given for \glspl{SDS} that
-reside on the client. Not all types are suitable to be located on a client,
-simply because it needs to be representable on clients. Moreover, \glspl{SDS}
-behave a little different in an \gls{mTask} device compared to in the
-\gls{iTasks} system. In an \gls{iTasks} system, when the \gls{SDS} is updated,
-a broadcast to all watching \glspl{Task} in the system is made to notify them
-of the update. \glspl{SDS} can update often and the update might not be the
-final value it will get. Implementing the same functionality on the \gls{mTask}
-client would result in a lot of expensive unneeded bandwidth usage. Therefore
-a device must publish the \gls{SDS} explicitly to save bandwidth.
-
-To add this functionality, the \CI{sds} class could be extended. However, this
-would result in having to update all existing views that use the \CI{sds}
-class. Therefore, an extra class is added that contains the extra
-functionality. Programmers can choose to implement it for existing views in the
-future but are not obliged to. The publication function has the following
-signature:
-\begin{lstlisting}[caption={The \texttt{sdspub} class}]
-class sdspub v where
- pub :: (v t Upd) -> v t Expr | type t
-\end{lstlisting}
-
-\section{Bytecode compilation view}\label{sec:compiler}
The \gls{mTask}-\glspl{Task} are sent to the device in bytecode and are saved
in the memory of the device. To compile the \gls{EDSL} code to bytecode, a view
is added to the \gls{mTask}-system encapsulated in the type \CI{ByteCode}. As
\subsection{Instruction Set}\label{sec:instruction}
The instruction set is given in Listing~\ref{bc:instr}. The instruction set is
-kept large, but under $255$, to get as much expressive power as possible while
-keeping all instruction within one byte.
+kept large, but the number of instructions stays under $255$ to get as much
+expressive power while keeping all instruction within one byte.
The interpreter running in the client is a stack machine. The virtual
instruction \CI{BCLab} is added to allow for an easy implementation of jumping.
\end{lstlisting}
All assignable types compile to a \gls{RWST} which writes the specific fetch
-instruction(s). For example, using an \gls{SDS} always results in an expression
-of the form \CI{sds \x=4 In ...}. The actual \CI{x} is the \gls{RWST} that
-always writes one \CI{BCSdsFetch} instruction with the correctly embedded
-\gls{SDS}. Assigning to an analog pin will result in the \gls{RWST} containing
-the \CI{BCAnalogRead} instruction. When the operation on the assignable is not
-a read operation from but an assign operation, the instruction(s) will be
-rewritten accordingly. This results in a \CI{BCSdsStore} or \CI{BCAnalogWrite}
-instruction respectively. The implementation for this is given in
-Listing~\ref{lst:assignmentview}.
+instruction(s). For example, using an \gls{SDS} always results in an
+expression of the form \CI{sds \x=4 In ...}. The actual \CI{x} is the
+\gls{RWST} that always writes one \CI{BCSdsFetch} instruction with the
+correctly embedded \gls{SDS}. Assigning to an analog pin will result in the
+\gls{RWST} containing the \CI{BCAnalogRead} instruction. When the operation on
+the assignable is not a read operation from but an assign operation, the
+instruction(s) will be rewritten accordingly. This results in a \CI{BCSdsStore}
+or \CI{BCAnalogWrite} instruction respectively. The implementation for this is
+given in Listing~\ref{lst:assignmentview}.
\begin{lstlisting}[label={lst:assignmentview},%
caption={Bytecode view implementation for assignment.}]
# newsdss = difference newstate.sdss oldstate.sdss
= ([MTSds sdsi e\\{sdsi,sdsval=e}<-newsdss] ++ [MTTask interval bc], newstate)
\end{lstlisting}
-
-\section{Examples}
-The thermostat example given previously in Listing~\ref{lst:exmtask} would be
-compiled to the following code. The left column indicates the
-position in the program memory.
-
-\begin{lstlisting}[caption={Thermostat bytecode},language=c]
- 1-2 : BCAnalogRead (Analog A0)
- 3-6 : BCPush (Int 50)
- 7 : BCGre
- 8-9 : BCJmpF 17 //Jump to else
-10-12: BCPush (Bool 1)
-13-14: BCDigitalWrite (Digital D0)
-15-16: BCJmp 21 //Jump to end of if
-17-19: BCPush (Bool 0) //Else label
-20 : BCDigitalWrite (Digital D0)
-\end{lstlisting}
--- /dev/null
+The thermostat example given previously in Listing~\ref{lst:exmtask} would be
+compiled to the following code. The left column indicates the
+position in the program memory.
+
+\begin{lstlisting}[caption={Thermostat bytecode},language=c]
+ 1-2 : BCAnalogRead (Analog A0)
+ 3-6 : BCPush (Int 50)
+ 7 : BCGre
+ 8-9 : BCJmpF 17 //Jump to else
+10-12: BCPush (Bool 1)
+13-14: BCDigitalWrite (Digital D0)
+15-16: BCJmp 21 //Jump to end of if
+17-19: BCPush (Bool 0) //Else label
+20 : BCDigitalWrite (Digital D0)
+\end{lstlisting}
--- /dev/null
+\Gls{mTask}-\glspl{SDS} on a client are available on the server as in the form
+of regular \gls{iTasks}-\glspl{SDS}. However, the same freedom that an
+\gls{SDS} has in the \gls{iTasks}-system is not given for \glspl{SDS} that
+reside on the client. Not all types are suitable to be located on a client,
+simply because it needs to be representable on clients. Moreover, \glspl{SDS}
+behave a little different in an \gls{mTask} device compared to in the
+\gls{iTasks} system. In an \gls{iTasks} system, when the \gls{SDS} is updated,
+a broadcast to all watching \glspl{Task} in the system is made to notify them
+of the update. \glspl{SDS} can update often and the update might not be the
+final value it will get. Implementing the same functionality on the \gls{mTask}
+client would result in a lot of expensive unneeded bandwidth usage. Therefore
+a device must publish the \gls{SDS} explicitly to save bandwidth.
+
+To add this functionality, the \CI{sds} class could be extended. However, this
+would result in having to update all existing views that use the \CI{sds}
+class. Therefore, an extra class is added that contains the extra
+functionality. Programmers can choose to implement it for existing views in the
+future but are not obliged to. The publication function has the following
+signature:
+\begin{lstlisting}[caption={The \texttt{sdspub} class}]
+class sdspub v where
+ pub :: (v t Upd) -> v t Expr | type t
+\end{lstlisting}
--- /dev/null
+The current \gls{mTask} engine for devices does not support \glspl{Task} in the
+sense that the \gls{C}-view does. \Glspl{Task} used with the \gls{C}-view are a
+main program that executes code and launches \glspl{Task}. It was also possible
+to just have a main program. The current \gls{mTask}-system only supports main
+programs. Sending a \gls{Task} always goes together with choosing a scheduling
+strategy. This strategy can be one of the following three strategies as
+reflected in the \CI{MTTask} message type.
+
+\begin{itemize}
+ \item\CI{OneShot}
+
+ \CI{OneShot} takes no parameters and means that the \gls{Task} will run
+ once and will then be removed automatically. This type of scheduling
+ could be useful, for example, in retrieving sensor information on
+ request of a user.
+ \item\CI{OnInterval}
+
+ \CI{OnInterval} has the number of milliseconds to wait in between
+ executions as a parameter. \Glspl{Task} running with this scheduling
+ method are executed at predetermined intervals.
+ \item\CI{OnInterrupt}
+
+ The last scheduling method is running \glspl{Task} on a specific
+ interrupt. Unfortunatly, due to time constraints and focus, none of the
+ current client implementations support this. Interrupt scheduling is
+ useful for \glspl{Task} that have to react on a certain type of
+ hardware event such as the press of a button.
+\end{itemize}
--- /dev/null
+The \glspl{Task} suitable for a client are called \gls{mTask}-\gls{Task} and
+are written in the aforementioned \gls{mTask}-\gls{EDSL}. Some functionality of
+the original \gls{mTask}-\gls{EDSL} will not be used in this system.
+Conversely, some functionality needed was not available in the existing
+\gls{EDSL}. Due to the nature of class based shallow embedding this obstacle is
+easy to solve. A type --- housing the \gls{EDSL} --- does not have to implement
+all the available classes. Moreover, classes can be added at will without
+interfering with the existing views.
+
+\section{\gls{Task} Semantics}
+\input{mtaskext.tasksem}
+
+\section{\gls{SDS} semantics}
+\input{mtaskext.sdssem}
+
+\section{Bytecode compilation view}\label{sec:compiler}
+\input{mtaskext.bytecode}
+
+\section{Examples}
+\input{mtaskext.examples}
+++ /dev/null
-The goal of the system as a whole is to offer a framework of functions with
-which an \gls{iTasks}-system can add, change and remove devices at runtime.
-Moreover, the \gls{iTasks}-system can send \gls{mTask}-\glspl{Task} ---
-compiled at runtime to bytecode by the \gls{mTask}-view --- to the device. The
-device runs an interpreter which can execute the \gls{Task}'s bytecode. Device
-profiles should be persistent during reboots of the \gls{iTasks}-system. The
-methods of interacting with \gls{mTask}-\gls{Task} should be analogous to
-interacting with \gls{iTasks}-\glspl{Task}. This means that programmers can
-access the \glspl{SDS} made for a device in the same way as regular \glspl{SDS}
-and they can execute \gls{mTask}-\glspl{Task} as if they where normal
-\gls{iTasks}-\glspl{Task}.
-
-The following terms will be used throughout the following chapter:
-\begin{itemize}
- \item Device, Client
-
- These terms denotes the actual device connected to the system. This can
- be a real device such as a microcontroller but it can also just be a
- program on the same machine as the server functioning as a client.
- \item Server, \gls{iTasks}-System
-
- This is the actual executable serving the \gls{iTasks} application. The
- system contains \glspl{Task} taking care of the communication with the
- clients.
- \item System
-
- The system describes the complete ecosystem, containing both the server
- and the clients including the communication between them.
- \item Engine
-
- The runtime system of the client is called the engine. This program
- handles communicating with the server and runs the interpreter for the
- \glspl{Task} on the client.
-\end{itemize}
-
-\section{Devices}
-A device is suitable for the system if it can run the engine.
-The engine is compiled from one codebase and devices implement (part of) the
-device specific interface. The shared codebase only uses standard \gls{C} and
-no special libraries or tricks are used. Therefore, the code is compilable for
-almost any device or system. Note that it is not needed to implement a full
-interface. The full interface --- excluding the device specific settings --- is
-listed in Appendix~\ref{app:device-interface}. The interface works in a
-similar fashion as the \gls{EDSL}. Devices do not have to implement all
-functionality, this is analogous to the fact that views do not have to
-implement all type classes in the \gls{EDSL}. When the device connects with
-the server for the first time, the specifications of what is implemented is
-communicated.
-
-At the time of writing the following device families are supported and can run
-the device software.
-\begin{itemize}
- \item \texttt{POSIX} compatible systems connected via the \gls{TCP}.
-
- This includes systems running \emph{Linux} and \emph{MacOS}.
- \item The \texttt{STM32} microcontrollers family supported by
- \texttt{ChibiOS} connected via serial communication.
-
- This is tested in particular on the \texttt{STM32f7x} series \gls{ARM}
- development board.
- \item Microcontrollers which are programmable in the \gls{Arduino} \gls{IDE}
- connected via serial communication or via \gls{TCP} over WiFi or
- Ethernet.
-
- This does not only include \gls{Arduino} compatible boards but also
- other boards capable of running \gls{Arduino} code. A port of the
- client has been made for the \texttt{ESP8266} powered \emph{NodeMCU}
- that is connected via \gls{TCP} over WiFi. A port also has been made
- for the regular \gls{Arduino} \emph{UNO} board which only boasts a
- meager \emph{2K} \emph{RAM}. The stack size and storage available for
- devices boasting this little \emph{RAM} has to be smaller than default
- but are still suitable to hold a hand full of \glspl{Task}.
-\end{itemize}
-
-\subsection{Client}
-\subsubsection{Engine}
-The client is in a constant loop listening for input and waiting to execute
-\glspl{Task}. The pseudocode for this is shown in Algorithm~\ref{alg:client}.
-The \CI{input\_available} function waits for input, but has a timeout set which
-can be interrupted. The timeout of the function determines the amount of loops
-per time interval and is a parameter that can be set during compilation for a
-device.
-
-\begin{algorithm}
- \KwData{
- \textbf{list} $tasks$,
- \textbf{time} $tm$
- }
-
- \Begin{
- \While{true}{
- \If{input\_available$()$}{
- receive\_data()\;
- }
-
- $tm\leftarrow \text{now}()$\;
- \ForEach{$t\leftarrow tasks$}{
- \uIf{is\_interrupt$(t)$ \textbf{and} had\_interrupt$(t)$}{
- run\_task$(t)$\;
- }
- \ElseIf{$tm-t.\text{lastrun} > t.\text{interval}$}{
- run\_task$(t)$\;
- \uIf{$t.\text{interval}==0$}{
- delete\_task$(t)$\;
- }\Else{
- $t.\text{lastrun}\leftarrow t$\;
- }
- }
- }
- }
- }
- \caption{Engine pseudocode}\label{alg:client}
-\end{algorithm}
-
-\subsubsection{Storage}
-\glspl{Task} and \glspl{SDS} are stored on the client in memory. Some devices
-have very little memory and therefore memory space is very expensive and needs
-to be used optimally. Almost all microcontrollers support heaps nowadays,
-however, the functions for allocating and freeing the memory on the heap are
-not very space optimal and often leave holes in the heap if allocations are not
-freed in reverse order. To overcome this problem the client will allocate a big
-memory segment in the global data block. This block of memory resides under the
-stack and its size can be set in the interface implementation. This block of
-memory will be managed in a similar way as the entire memory space of the
-device is managed. \Glspl{Task} will grow from the bottom up and \glspl{SDS}
-will grow from the top down.
-
-When a \gls{Task} is received, the program will traverse the memory space from
-the bottom up, jumping over all \glspl{Task}. A \gls{Task} is stored as the
-structure followed directly by its bytecode. Therefore it only takes two jumps
-to determine the size of the \gls{Task}. When the program arrived at the last
-\gls{Task}, this place is returned and the newly received \gls{Task} can be
-copied to there. This method is analogously applied for \glspl{SDS}, however,
-the \glspl{SDS} grow from the bottom down.
-
-When a \gls{Task} or \gls{SDS} is removed, all remaining objects are compressed
-again. This means that if the first received \gls{Task} is removed, all
-\glspl{Task} received later will have to move back. Obviously, this is quite
-time intensive but it can not be permitted to leave holes in the memory since
-the memory space is so limited. This techniques allows for even the smallest
-tested microcontrollers with only $2K$ \emph{RAM} to hold several \glspl{Task}
-and \glspl{SDS}. If this technique would not be used the memory space will
-decrease over time and the client can then not run for very long since holes
-are evidently created at some point.
-
-The structure instances and helper functions for traversing them in memory for
-\glspl{Task} and \glspl{SDS} are shown in Listing~\ref{lst:structs}.
-
-\begin{lstlisting}[language=C,label={lst:structs},%
- caption={The data type storing the \glspl{Task}},float]
-struct task {
- uint16_t tasklength;
- uint16_t interval;
- unsigned long lastrun;
- uint8_t taskid;
- uint8_t *bc;
-};
-
-struct task *task_head(void);
-struct task *task_next(struct task *t);
-
-struct sds {
- int id;
- int value;
- char type;
-};
-
-struct sds *sds_head(void);
-struct sds *sds_next(struct sds *s);
-\end{lstlisting}
-
-\subsubsection{Interpretation}
-The execution of a \gls{Task} is started by running the \CI{run\_task} function
-and always starts with setting the program counter and stack
-pointer to zero and the bottom respectively. When finished, the
-interpreter executes one step at the time while the program counter is smaller
-than the program length. This code is listed in Listing~\ref{lst:interpr}. One
-execution step is basically a big switch statement going over all possible
-bytecode instructions. Of some instructions, the implementations are shown in
-the listing. The \CI{BCPush} instruction is a little more complicated in the
-real code because some decoding will take place as not all \CI{BCValue}s are of
-the same length and are encoded.
-
-\begin{lstlisting}[language=C,label={lst:interpr},%
- caption={Rough code outline for interpretation}]
-#define f16(p) program[pc]*265+program[pc+1]
-
-void run_task(struct task *t){
- uint8_t *program = t->bc;
- int plen = t->tasklength;
- int pc = 0;
- int sp = 0;
- while(pc < plen){
- switch(program[pc++]){
- case BCNOP:
- break;
- case BCPUSH:
- stack[sp++] = pc++ //Simplified
- break;
- case BCPOP:
- sp--;
- break;
- case BCSDSSTORE:
- sds_store(f16(pc), stack[--sp]);
- pc+=2;
- break;
- // ...
- case BCADD: trace("add");
- stack[sp-2] = stack[sp-2] + stack[sp-1];
- sp -= 1;
- break;
- // ...
- case BCJMPT: trace("jmpt to %d", program[pc]);
- pc = stack[--sp] ? program[pc]-1 : pc+1;
- break;
-}
-\end{lstlisting}
-
-\subsection{Specification}
-The server stores a description for every device available in a record type.
-From the macro settings in the interface file, a profile is created that
-describes the specification of the device. When the connection between the
-server and a client is established, the server will send a request for
-specification. The client serializes its specification and send it to the
-server so that the server knows what the client is capable of. The exact
-specification is shown in Listing~\ref{lst:devicespec} and stores the
-peripheral availability, the memory available for storing \glspl{Task} and
-\glspl{SDS} and the size of the stack.
-
-\begin{lstlisting}[label={lst:devicespec},
- caption={Device specification for \gls{mTask}-\glspl{Task}}]
-:: MTaskDeviceSpec =
- { haveLed :: Bool
- , haveLCD :: Bool
- , have...
- , bytesMemory :: Int
- , stackSize :: Int
- , aPins :: Int
- , dPins :: Int
- }
-\end{lstlisting}
-
-\section{iTasks}
-The server part of the system is written in \gls{iTasks}. Functions for
-managing devices, \glspl{Task} and \glspl{SDS} have been created to support the
-functionality. An interactive web application has been created that provides an
-interactive management console for the \gls{mTask} system. This interface
-provides functionality to list \glspl{SDS}, add and remove \glspl{Task},
-administrate devices and view the state of the system.
-
-\subsection{Device Storage}
-Everything that a device encompasses is stored in the \CI{MTaskDevice} record
-type. This includes management for the \glspl{SDS} and \glspl{Task} stored on
-the device. The \CI{MTaskDevice} definition is shown in
-Listing~\ref{lst:mtaskdevice} accompanied with the necessary classes and sub
-types.
-
-\begin{lstlisting}[caption={Device type},label={lst:mtaskdevice}]
-:: Channels :== ([MTaskMSGRecv], [MTaskMSGSend], Bool)
-:: BCState = ... // Compiler state, explained in later sections
-:: MTaskResource
- = TCPDevice TCPSettings
- | SerialDevice TTYSettings
- | ...
-:: MTaskDevice =
- { deviceTask :: Maybe TaskId
- , deviceError :: Maybe String
- , deviceChannels :: String
- , deviceName :: String
- , deviceState :: BCState
- , deviceTasks :: [MTaskTask]
- , deviceResource :: MTaskResource
- , deviceSpec :: Maybe MTaskDeviceSpec
- , deviceShares :: [MTaskShare]
- }
-
-channels :: MTaskDevice -> Shared Channels
-
-class MTaskDuplex a where
- synFun :: a (Shared Channels) -> Task ()
-\end{lstlisting}
-
-The \CI{deviceResource} component of the record must implement the
-\CI{MTaskDuplex} interface that provides a function that launches a \gls{Task}
-used for synchronizing the channels. The \CI{deviceTask} stores the
-\gls{Task}-id for this \gls{Task} when active so that it can be checked upon.
-This top-level task has the duty to report exceptions and errors as they are
-thrown by setting the \CI{deviceError} field. All communication goes via these
-channels. To send a message to the device, the system just puts it
-in the channels. Messages sent from the client to the server are also placed
-in there. In the case of the \gls{TCP} device type, the \gls{Task} is just a
-simple wrapper around the existing \CI{tcpconnect} function in \gls{iTasks}. In
-case of a device connected by a serial connection, it uses the newly developed
-serial port library of \gls{Clean}\footnote{\url{%
-https://gitlab.science.ru.nl/mlubbers/CleanSerial}}.
-
-Besides all the communication information, the record also keeps track of the
-\glspl{Task} currently on the device, the compiler state (see
-Section~\ref{sec:compiler}) and the according \glspl{SDS}. Finally, it stores
-the specification of the device that is received when connecting. All of this
-is given in Listing~\ref{lst:mtaskdevice}. The definitions of the message
-format are explained in the following section.
-
-\subsection{Shares}
-The system keeps track of the \glspl{SDS} stored on
-the client in a big \gls{SDS} containing a list of devices. Client-\glspl{SDS}
-can be stored on one device at the same time. This means that if an \gls{SDS}
-updates, everyone watching it will be notified. This would result in a lot
-of notifications that are not meant for the watcher. Moreover, when a client
-updates the \gls{SDS} this is processed by the connection handler and results
-in an update of the real \gls{SDS}. Finally, the \gls{SDS} of a client must be
-synchronized with the actual device. Thus, when an \gls{iTasks}-\gls{Task}
-writes the client-\gls{SDS}, it must be propagated to the real device. There
-are several ways of tackling this problem each with their own level of
-granularity.
-
-First an actual \gls{iTasks}-\gls{SDS} for every \gls{SDS} used in a client can
-be instantiated with one \gls{iTasks}-\gls{Task} listening to the \gls{SDS} and
-synchronizing it with the device when an update occurred. This approach is very
-expensive as it requires a lot of listening \glspl{Task}.
-
-Improved on this, a single \gls{iTasks}-\gls{SDS} can be created for every
-devices that stores the respective \glspl{SDS}. Using the \CI{mapReadWrite}
-functions, a single \gls{SDS} per device can be created as a lens that allows
-mapping on a single client-\gls{SDS}. However, this approach still requires
-\glspl{Task} listening to the \gls{SDS} and when an \gls{SDS} is written,
-everyone is notified, even if the \gls{Task} only uses the value of a single
-different \gls{SDS}.
-
-Finally, the current approach --- a single \gls{SDS} for the entire system
---- was explored. To create \glspl{SDS} per device or per client-\glspl{SDS} a
-\CI{mapReadWrite} can be used but it suffers from the same problem as mentioned
-before. Moreover, a \gls{Task} still has to watch the \gls{SDS} and communicate
-the client-\gls{SDS} updates to the actual device. Both of these problems can
-be solved by using a tailor made \gls{SDS} that heavily depends on parametric
-lenses.
-
-\subsection{Parametric Lenses}
-The type for the parametric lens of the big \gls{SDS} is \CI{Maybe
-(MTaskDevice, Int)}. The \gls{SDS} is responsible for storing the entire list
-of devices, from now on global. Moreover, the \gls{SDS} can focus on a single
-device, from now on local. A local \gls{SDS} can also specifically focus on a
-single \gls{SDS} on a single device, from now on called local-share. The
-implementation of the real \gls{SDS} is given in Listing~\ref{lst:actualdev}.
-The \gls{SDS} is a lens on an actual \gls{SDS} that writes to a file or memory.
-Reading the \gls{SDS} is nothing more than reading the real \gls{SDS}. Writing
-the \gls{SDS} is a little bit more involved. If the write operation originated
-from an \gls{SDS} focussed on a single client-\gls{SDS}, the write action must
-also be relayed to the actual device. If the write originated from an \gls{SDS}
-focussed the devices or on one device only, nothing needs to be done. The
-notification predicate determines whether a watcher gets a notification update.
-
-\begin{lstlisting}[label={lst:actualdev},%
- caption={Device \gls{SDS}}]
-deviceStore :: RWShared (Maybe (MTaskDevice, Int)) [MTaskDevice] [MTaskDevice]
-deviceStore = SDSSource {SDSSource | name="deviceStore", read = realRead, write= realWrite}
-where
- realRead :: (Maybe (MTaskDevice,Int)) *IWorld -> (MaybeError TaskException [MTaskDevice], *IWorld)
- realRead p iw = read realDeviceStore iw
-
- realWrite :: (Maybe (MTaskDevice,Int)) [MTaskDevice] *IWorld -> (MaybeError TaskException (SDSNotifyPred (Maybe (MTaskDevice,Int))), *IWorld)
- realWrite mi w iw
- # (merr, iw) = write w realDeviceStore iw
- | isError merr || isNothing mi = (merr $> notifyPred mi, iw)
- # (Just (dev, ident)) = mi
- | ident == -1 = (merr $> notifyPred mi, iw)
- = case find ((==)dev) w of
- Nothing = (Error $ exception "Device lost", iw)
- Just {deviceShares} = case find (\d->d.identifier == ident) deviceShares of
- Nothing = (Error $ exception "Share lost", iw)
- Just s = case sendMessagesIW [MTUpd ident s.MTaskShare.value] dev iw of
- (Error e, iw) = (Error e, iw)
- (Ok _, iw) = (Ok $ notifyPred mi, iw)
-
- notifyPred :: (Maybe (MTaskDevice, Int)) (Maybe (MTaskDevice, Int)) -> Bool
- notifyPred Nothing Nothing = True // Global watcher looking at a global event
- notifyPred Nothing (Just _) = False // Global watcher looking at a local event
- notifyPred (Just _) Nothing = False // Local watcher looking at a global event
- // Local device watcher looking at a local event
- notifyPred (Just (d1, -1)) (Just (d2, _)) = d1 == d2
- // Local share watcher looking at a local share event
- notifyPred (Just (d1, i1)) (Just (d2, i2)) = d1 == d2 && i1 == i2
-
- realDeviceStore :: Shared [MTaskDevice]
- realDeviceStore = sharedStore "mTaskDevices" []
-\end{lstlisting}
-
-\subsubsection{Global \glspl{SDS}}
-Accessing the global \gls{SDS} is just a matter of focussing the
-\CI{deviceStore} with the \CI{Nothing} parameter as follows:
-
-\begin{lstlisting}[caption={Global \gls{SDS}}]
-deviceStoreNP :: Shared [MTaskDevice]
-deviceStoreNP = sdsFocus Nothing deviceStore
-\end{lstlisting}
-
-\subsubsection{Local \glspl{SDS}}
-Accessing a single device can be done using the \CI{mapReadWrite} function.
-Since device comparison is shallow, the device that is given is allowed to be
-an old version. The identification of devices is solely done on the name of the
-channels and is unique throughout the system. The implementation is as follows:
-
-\begin{lstlisting}[caption={Local \gls{SDS}}]
-deviceShare :: MTaskDevice -> Shared MTaskDevice
-deviceShare d = mapReadWriteError
- ( \ds->case find ((==)d) of
- Nothing = exception "Device lost"
- Just d = Ok d)
- , \w ds->case splitWith ((==)d) ds of
- ([], _) = Error $ exception "Device lost"
- ([_:_], ds) = Ok $ Just [w:ds])
- $ sdsFocus (Just (d, -1)) deviceStore
-\end{lstlisting}
-
-\subsubsection{Local-\gls{SDS} specific \glspl{SDS}}
-A single \gls{SDS} on a single device can be accessed using the \CI{shareShare}
-function. This function focusses the real big \gls{SDS} on a single \gls{SDS}
-and uses the \CI{mapReadWrite} functions to serve the correct part of the
-information.
-
-\begin{lstlisting}[caption={Local \gls{SDS}}]
-shareShare :: MTaskDevice MTaskShare -> Shared BCValue
-shareShare dev share = sdsFocus ()
- $ mapReadWriteError (read, write)
- $ sdsFocus (Just (dev, share.identifier))
- $ deviceStore
-where
- read :: [MTaskDevice] -> MaybeError TaskException BCValue
- read devs = case find ((==)dev) devs of
- Nothing = exception "Device lost"
- Just d = case find ((==)share) d.deviceShares of
- Nothing = exception "Share lost"
- Just s = Ok s.MTaskShare.value
-
- write :: BCValue [MTaskDevice] -> MaybeError TaskException (Maybe [MTaskDevice])
- write val devs = case partition ((==)dev) devs of
- ([], _) = Error $ exception "Device doesn't exist anymore"
- ([_,_:_], _) = Error $ exception "Multiple matching devices"
- ([d=:{deviceShares}], devs) = case partition ((==)share) deviceShares of
- ([], _) = Error $ exception "Share doesn't exist anymore"
- ([_,_:_], _) = Error $ exception "Multiple matching shares"
- ([s], shares) = Ok $ Just [{MTaskDevice | d &
- deviceShares=[{MTaskShare | s & value=val}:shares]}:devs]
-\end{lstlisting}
-
-\section{Communication}
-The communication from the server to the client and vice versa is just a
-character stream containing encoded \gls{mTask} messages. The \CI{synFun}
-belonging to the device is responsible for sending the content in the left
-channel and putting received messages in the right channel. Moreover, the
-boolean value should be set to \CI{True} when the connection is terminated. The
-specific encoding of the messages is visible in
-Appendix~\ref{app:communication-protocol}. The type holding the messages is
-shown in Listing~\ref{lst:avmsg}. Detailed explanation about the message types
-and according actions will be given in the following subsections.
-
-\begin{lstlisting}[label={lst:avmsg},caption={Available messages}]
-:: MTaskId :== Int
-:: MSDSId :== Int
-:: MTaskFreeBytes :== Int
-:: MTaskMSGRecv
- = MTTaskAck MTaskId MTaskFreeBytes | MTTaskDelAck MTaskId
- | MTSDSAck MSDSId | MTSDSDelAck MSDSId
- | MTPub MSDSId BCValue | MTMessage String
- | MTDevSpec MTaskDeviceSpec | MTEmpty
-
-:: MTaskMSGSend
- = MTTask MTaskInterval String | MTTaskDel MTaskId
- | MTShutdown | MTSds MSDSId BCValue
- | MTUpd MSDSId BCValue | MTSpec
-
-:: MTaskInterval = OneShot | OnInterval Int | OnInterrupt Int
-\end{lstlisting}
-
-\subsection{Add a device}
-A device can be added by filling in the \CI{MTaskDevice} record as much as
-possible and running the \CI{connectDevice} function. This function grabs the
-channels, starts the synchronization \gls{Task} (\CI{synFun}), makes sure the
-errors are handled when needed and runs a processing function in parallel to
-react on the incoming messages. Moreover, it sends a specification request to
-the device in question to determine the details of the device and updates the
-record to contain the top-level \gls{Task}-id. All device functionality
-heavily depends on the specific \CI{deviceShare} function that generates an
-\gls{SDS} for a specific device. This allows giving an old device record to the
-function and still update the latest instance. Listing~\ref{lst:connectDevice}
-shows the connection function.
-
-\begin{lstlisting}[label={lst:connectDevice},%
- caption={Connect a device}]
-connectDevice :: (MTaskDevice (Shared Channels) -> Task ()) MTaskDevice -> Task Channels
-connectDevice procFun device = set ([], [], False) ch
- >>| appendTopLevelTask 'DM'.newMap True
- ( procFun device ch -||- catchAll (getSynFun device.deviceData ch) errHdl)
- >>= \tid->upd (\d->{d&deviceTask=Just tid,deviceError=Nothing}) (deviceShare device)
- >>| upd (\(r,s,ss)->(r,s++[MTSpec],ss)) ch
-where
- errHdl e = upd (\d->{d & deviceTask=Nothing, deviceError=Just e}) (deviceShare device) @! ()
- ch = channels device
-\end{lstlisting}
-
-Figure~\ref{fig:handshake} shows the connection diagram. The client responds to
-the server with their device specification. This is detected by the processing
-function and the record is updated accordingly.
-
-\begin{figure}[H]
- \centering
- \begin{sequencediagram}
- \newthread{s}{Server}
- \newinst[4]{c}{Client}
- \begin{call}{s}{MTSpec}{c}{MTDevSpec}
- \end{call}
- \end{sequencediagram}
- \caption{Connect a device}\label{fig:handshake}
-\end{figure}
-
-\subsection{\glspl{Task} \& \glspl{SDS}}
-When a \gls{Task} is sent to the device it is added to the device record
-without an identifier. The actual identifier is added to the record when the
-acknowledgement of the \gls{Task} by the device is received. The connection
-diagram is shown in Figure~\ref{fig:tasksend}.
-
-\begin{figure}[H]
- \centering
- \begin{sequencediagram}
- \newthread{s}{Server}
- \newinst[4]{c}{Client}
- \begin{call}{s}{MTSDS}{c}{MTSDSAck}
- \end{call}
- \begin{call}{s}{MTTask}{c}{MTTaskAck}
- \end{call}
- \end{sequencediagram}
- \caption{Sending a \gls{Task} to a device}\label{fig:tasksend}
-\end{figure}
-
-The function for sending a \gls{Task} to the device is shown in
-Listing~\ref{lst:sendtask}. First the \gls{Task} is compiled into messages. The
-details of the compilation process are given in Section~\ref{sec:compiler}.
-The new \glspl{SDS} that were generated during compilation are merged with the
-existing device's \glspl{SDS}. Furthermore the messages are placed in the
-channel \gls{SDS} of the device. This will result in sending the actual \gls{SDS}
-specification and \gls{Task} specifications to the device. A \gls{Task} record
-is created with the identifier $-1$ to denote a \gls{Task} not yet
-acknowledged. Finally the device itself is updated with the new state and with
-the new \gls{Task}. After waiting for the acknowledgement the device is
-updated again and the \gls{Task} returns.
-
-\begin{lstlisting}[label={lst:sendtask},%
- caption={Sending a \gls{Task} to a device}]
-makeTask :: String Int -> Task MTaskTask
-makeTask name ident = get currentDateTime @ \dt->{MTaskTask | name=name, ident=ident, dateAdded=dt}
-
-makeShare :: String Int BCValue -> MTaskShare
-makeShare withTask identifier value = {MTaskShare | withTask=[withTask], identifier=identifier, value=value}
-
-sendTaskToDevice :: String (Main (ByteCode a Stmt)) (MTaskDevice, MTaskInterval) -> Task MTaskTask
-sendTaskToDevice wta mTask (device, timeout)
-# (msgs, newState=:{sdss}) = toMessages timeout mTask device.deviceState
-# shares = [makeShare wta "" sdsi sdsval\\{sdsi,sdsval}<-sdss, (MTSds sdsi` _)<-msgs | sdsi == sdsi`]
-= updateShares device ((++) shares)
- >>| sendMessages msgs device
- >>| makeTask wta -1
- >>= \t->upd (addTaskUpState newState t) (deviceShare device)
- >>| wait "Waiting for task to be acked" (taskAcked t) (deviceShare device)
- >>| treturn t
-where
- addTaskUpState :: BCState MTaskTask MTaskDevice -> MTaskDevice
- addTaskUpState st task device = {MTaskDevice | device & deviceState=st, deviceTasks=[task:device.deviceTasks]}
- taskAcked t d = maybe True (\t->t.ident <> -1) $ find (eq t) d.deviceTasks
- eq t1 t2 = t1.dateAdded == t2.dateAdded && t1.MTaskTask.name == t2.MTaskTask.name
-\end{lstlisting}
-
-\subsection{Miscellaneous Messages}
-One special type of message is available which is sent to the device only when
-it needs to reboot. When the server wants to stop the bond with the device it
-sends the \CI{MTShutdown} message. The device will then clear its memory, thus
-losing all the \glspl{SDS} and \glspl{Task} that were stored and reset itself.
-Shortly after the shutdown message a new server can connect to the device
-because the device is back in listening mode.
-
-\subsection{Integration}
-When the system starts up, the devices from the previous execution still
-residing in the \gls{SDS} must be cleaned up. It might be the case that they
-contain \glspl{Task}, \glspl{SDS} or errors that are no longer applicable in
-this run. A user or programmer can later choose to reconnect to some devices.
-
-\begin{lstlisting}[caption={Starting up the devices},%
- label={lst:startupdevs}]
-startupDevices :: Task [MTaskDevice]
-startupDevices = upd (map reset) deviceStoreNP
- where reset d = {d & deviceTask=Nothing, deviceTasks=[], deviceError=Nothing}
-\end{lstlisting}
-
-The system's management is done through the interface of a single \gls{Task}
-called \CI{mTaskManager}. To manage the system, a couple of different
-functionalities are necessary and are launched. An image of the management
-interface is shown in Figure~\ref{lst:manage}. The left sidebar of the
-interface shows the list of example \glspl{Task} that are present in the
-system. When clicking a \gls{Task}, a dialog opens in which a device can be
-selected to send the \gls{Task} to. The dialog might contain user specified
-variables. All example \gls{mTask}-\glspl{Task} are of the type \CI{Task (Main
-(ByteCode () Stmt))} and can thus ask for user input first if needed for
-parameterized \gls{mTask}-\glspl{Task}. The bottom panel shows the device
-information. In this panel, the devices can be created and modified. Moreover,
-this panel allows the user to reconnect with a device after a restart of the
-server application.
-
-\begin{figure}[H]
- \centering
- \includegraphics[width=\linewidth]{manage}
- \caption{The device management interface}\label{lst:manage}
-\end{figure}
-
-\section[Lifting mTasks to iTasks-Tasks]%
- {Lifting \gls{mTask}-\glspl{Task} to \gls{iTasks}-\glspl{Task}}
-If the user does not want to know where and when a \gls{mTask} is actually
-executed and is just interested in the results it can lift the \gls{mTask} to
-an \gls{iTasks}-\gls{Task}. The function is called with a name, \gls{mTask},
-device and interval specification and it will return a \gls{Task} that finishes
-if and only if the \gls{mTask} has returned.
-
-\begin{lstlisting}[caption={Starting up the devices}]
-liftmTask :: String (Main (ByteCode () Stmt)) (MTaskDevice, MTaskInterval) -> Task ()
-liftmTask wta mTask c=:(dev, _)= sendTaskToDevice wta mTask c
- >>= \t->wait "Waiting for mTask to return" (taskRemoved t) (deviceShare dev)
- >>| viewInformation "Done!" [] ()
-where
- taskRemoved t d = isNothing $ find (\t1->t1.ident==t.ident) d.deviceTasks
-\end{lstlisting}
-
-\section{Examples}
-Here comes a description of the demo program.
\mainmatter{}
\glsresetall{}
\chapter{Introduction}\label{chp:introduction}
-\input{introduction}
+\input{intro}
\chapter{Task Oriented Programming}\label{chp:top}
-\input{methods.top}
+\input{top}
\chapter{Embedded Domain Specific Languages}\label{chp:dsl}
-\input{methods.dsl}
+\input{edsl}
\chapter[The mTask-EDSL]{The \gls{mTask}-\gls{EDSL}}\label{chp:mtask}
-\input{methods.mtask}
+\input{mtask}
\chapter[Extending the mTask EDSL]{Extending the \gls{mTask} {EDSL}}\label{chp:mtaskcont}
-\input{results.mtask}
+\input{mtaskext}
\chapter{System Architecture}\label{chp:arch}
-\input{results.arch}
+\input{arch}
\chapter{Discussion \& Conclusion}\label{chp:conclusion}
\input{conclusion}
--- /dev/null
+\Glspl{Task} can be combined using so called \gls{Task}-combinators.
+Combinators describe relations between \glspl{Task}. There are only two basic
+types of combinators; parallel and sequence. All other combinators are
+derived from the basic combinators. Type signatures of simplified versions of
+the basic combinators and their derivations are given in
+Listing~\ref{lst:combinators}
+
+\begin{lstlisting}[%
+ caption={\Gls{Task}-combinators},label={lst:combinators}]
+//Step combinator
+(>>=) infixl 1 :: (Task a) (a -> Task b) -> Task b | iTask a & iTask b
+(>>*) infixl 1 :: (Task a) [TaskCont a (Task b)] -> Task b | iTask a & iTask b
+:: TaskCont a b
+ = OnValue ((TaskValue a) -> Maybe b)
+ | OnAction Action ((TaskValue a) -> Maybe b)
+ | E.e: OnException (e -> b) & iTask e
+ | OnAllExceptions (String -> b)
+:: Action = Action String
+
+//Parallel combinators
+(-||-) infixr 3 :: (Task a) (Task a) -> Task a | iTask a
+(||-) infixr 3 :: (Task a) (Task b) -> Task b | iTask a & iTask b
+(-||) infixl 3 :: (Task a) (Task b) -> Task a | iTask a & iTask b
+(-&&-) infixr 4 :: (Task a) (Task b) -> Task (a,b) | iTask a & iTask b
+\end{lstlisting}
+
+\paragraph{Sequence:}
+The implementation for the sequence combinator is called the
+\CI{step} (\CI{>>*}). This combinator runs the left-hand \gls{Task} and
+starts the right-hand side when a certain predicate holds. Predicates
+can be propositions about the \CI{TaskValue}, user actions from within
+the web browser or a thrown exception. The familiar
+bind-combinator is an example of a sequence combinator. This combinator
+runs the left-hand side and continues to the right-hand \gls{Task} if
+there is an \CI{UnStable} value and the user presses continue or when
+the value is \CI{Stable}. The combinator could have been implemented
+as follows:
+\begin{lstlisting}[language=Clean]
+(>>=) infixl 1 :: (Task a) (a -> (Task b)) -> (Task b) | iTask a & iTask b
+(>>=) ta f = ta >>* [OnAction "Continue" onValue, OnValue onStable]
+ where
+ onValue (Value a _) = Just (f a)
+ onValue _ = Nothing
+
+ onStable (Value a True) = Just (f a)
+ onStable _ = Nothing
+\end{lstlisting}
+
+\paragraph{Parallel:}
+The parallel combinator allows for concurrent \glspl{Task}. The
+\glspl{Task} combined with these operators will appear at the same time
+in the web browser of the user and the results are combined as the type
+dictates. All parallel combinators used are derived from the basic parallel
+combinator that is very complex and only used internally.
--- /dev/null
+\gls{TOP} is a novel programming paradigm implemented as
+\gls{iTasks}~\cite{achten_introduction_2015} in the pure lazy functional
+language \gls{Clean}~\cite{brus_cleanlanguage_1987}. \gls{iTasks} is an
+\gls{EDSL} to model workflow tasks in the broadest sense. A \gls{Task} is just
+a function that --- given some state --- returns the observable \CI{TaskValue}.
+The \CI{TaskValue} of a \CI{Task} can have different states. Not all state
+transitions are possible as shown in Figure~\ref{fig:taskvalue}. Once a value
+is stable it can never become unstable again. Stability is often reached by
+pressing a confirmation button. \glspl{Task} yielding a constant value are
+immediately stable.
+
+A simple \gls{iTasks} example illustrating the route to stability of a
+\gls{Task} in which the user has to enter a full name is shown in
+Listing~\ref{lst:taskex}. The code is accompanied by screenshots showing the
+user interface in Figure~\ref{fig:taskex1},~\ref{fig:taskex2}
+and~\ref{fig:taskex3}. The \CI{TaskValue} of the \gls{Task} is in the first
+image in the \CI{NoValue} state, the second image does not have all the fields
+filled in and therefore the \CI{TaskValue} remains \CI{NoValue}. In the third
+image all fields are entered and the \CI{TaskValue} transitions to the
+\CI{Unstable} state. When the user presses \emph{Continue} the value becomes
+\CI{Stable} and cannot be changed any further.
+
+\begin{figure}[H]
+ \centering
+ \includegraphics[width=.5\linewidth]{fig-taskvalue}
+ \caption{The states of a \CI{TaskValue}}\label{fig:taskvalue}
+\end{figure}
+
+\begin{lstlisting}[label={lst:taskex},%
+ caption={An example \gls{Task} for entering a name}]
+:: Name = { firstname :: String
+ , lastname :: String
+ }
+
+derive class iTask Name
+
+enterInformation :: String [EnterOption m] -> (Task m) | iTask m
+
+enterName :: Task Name
+enterName = enterInformation "Enter your name" []
+\end{lstlisting}
+
+\begin{figure}[H]
+ \centering
+ \begin{subfigure}{.25\textwidth}
+ \centering
+ \includegraphics[width=.9\linewidth]{taskex1}
+ \caption{Initial interface}\label{fig:taskex1}
+ \end{subfigure}
+ \begin{subfigure}{.25\textwidth}
+ \centering
+ \includegraphics[width=.9\linewidth]{taskex2}
+ \caption{Incomplete entrance}\label{fig:taskex2}
+ \end{subfigure}
+ \begin{subfigure}{.25\textwidth}
+ \centering
+ \includegraphics[width=.9\linewidth]{taskex3}
+ \caption{Complete entry}\label{fig:taskex3}
+ \end{subfigure}
+ \caption{Example of a generated user interface}
+\end{figure}
+
+For a type to be suitable, it must have instances for a collection of generic
+functions that is captured in the class \CI{iTask}. Basic types have
+specialization instances for these functions and show an interface accordingly.
+Derived interfaces can be modified with decoration operators or specializations
+can be created.
+
--- /dev/null
+\Glspl{SDS} are an abstraction over resources that are available in the world
+or in the \gls{iTasks} system. The shared data can be a file on disk, the
+system time, a random integer or just some data stored in memory. The actual
+\gls{SDS} is just a record containing functions on how to read and write the
+source. In these functions the \CI{*IWorld} --- which in turn contains the real
+\CI{*World} --- is available. Accessing the outside world is required for
+interacting with it and thus the functions can access files on disk, raw
+memory, other \glspl{SDS} and hardware.
+
+The basic operations for \glspl{SDS} are get, set and update. The signatures
+for these functions are shown in Listing~\ref{lst:shares}. By default, all
+\glspl{SDS} are files containing a \gls{JSON} encoded version of the object and
+thus are persistent between restarts of the program. Library functions for
+shares residing in memory are available as well. The three main operations on
+shares are atomic in the sense that during reading no other \glspl{Task} are
+executed. The system provides useful functions to transform, map and combine
+\glspl{SDS} using combinators. The system also provides functionality to
+inspect the value of an \gls{SDS} and act upon a change. \Glspl{Task} waiting on
+an \gls{SDS} to change are notified when needed. This results in low resource
+usage because \glspl{Task} are never constantly inspecting \gls{SDS} values but
+are notified.
+
+\begin{lstlisting}[%
+ label={lst:shares},caption={\Gls{SDS} functions}]
+:: RWShared p r w = ...
+:: ReadWriteShared r w :== RWShared () r w
+:: ROShared p r :== RWShared p () r
+:: ReadOnlyShared r :== ROShared () r
+
+:: Shared r :== ReadWriteShared r r
+
+get :: (ReadWriteShared r w) -> Task r | iTask r
+set :: w (ReadWriteShared r w) -> Task w | iTask w
+upd :: (r -> w) (ReadWriteShared r w) -> Task w | iTask r & iTask w
+
+sharedStore :: String a -> Shared a | JSONEncode{|*|}, JSONDecode{|*|}
+\end{lstlisting}
+
+\section{Parametric Lenses}
+\Glspl{SDS} can contain complex data structures such as lists, trees and even
+resources in the outside world. Sometimes, an update action only updates a part
+of the resource. When this happens, all waiting \glspl{Task} looking at the
+resource are notified of the update. However, it may be the case that
+\glspl{Task} were only looking at parts of the structure that was not updated.
+To solve this problem, parametric lenses were
+introduced~\cite{domoszlai_parametric_2014}.
+
+Parametric lenses add a type variable to the \gls{SDS}. This type variable is
+fixed to the void type (i.e. \CI{()}) in the given functions. When an \gls{SDS}
+executes a write operation, it also provides the system with a notification
+predicate. This notification predicate is a function \CI{p -> Bool} where
+\CI{p} is the parametric lens type. This allows programmers to create a big
+\gls{SDS}, and have \glspl{Task} only look at parts of the big \gls{SDS}. This
+technique is used in the current system in memory shares. The \CI{IWorld}
+contains a map that is accessible through an \gls{SDS}. While all data is
+stored in the map, only \glspl{Task} looking at a specific entry are notified
+when the structure is updated. The type of the parametric lens is the key in
+the map.
+
+Functionality for setting parameters is available in the system. The most
+important functions are the \CI{sdsFocus} and the \CI{sdsLens} function. These
+functions are listed in Listing~\ref{lst:focus}. \CI{sdsFocus} allows the
+programmer to fix a parametric lens value. \CI{sdsLens} is a kind of
+\CI{mapReadWrite} including access to the parametric lens value. This allows
+the creation of, for example, \glspl{SDS} that only read and write to parts of
+the original \gls{SDS}.
+
+\begin{lstlisting}[label={lst:focus},
+ caption={Parametric lens functions}]
+sdsFocus :: p (RWShared p r w) -> RWShared p` r w | iTask p
+
+:: SDSNotifyPred p :== p -> Bool
+
+:: SDSLensRead p r rs = SDSRead (p -> rs -> MaybeError TaskException r)
+ | SDSReadConst (p -> r)
+:: SDSLensWrite p w rs ws = SDSWrite (p -> rs -> w -> MaybeError TaskException (Maybe ws))
+ | SDSWriteConst (p -> w -> MaybeError TaskException (Maybe ws))
+:: SDSLensNotify p w rs = SDSNotify (p -> rs -> w -> SDSNotifyPred p)
+ | SDSNotifyConst (p -> w -> SDSNotifyPred p)
+
+sdsLens :: String (p -> ps) (SDSLensRead p r rs) (SDSLensWrite p w rs ws) (SDSLensNotify p w rs)
+ (RWShared ps rs ws) -> RWShared p r w | iTask ps
+\end{lstlisting}
--- /dev/null
+\section{iTasks}
+\input{top.itasks}
+
+\section{Combinators}
+\input{top.combinators}
+
+\section{Shared Data Sources}
+\input{top.sds}