restructure files
authorMart Lubbers <mart@martlubbers.net>
Thu, 29 Jun 2017 18:42:22 +0000 (20:42 +0200)
committerMart Lubbers <mart@martlubbers.net>
Thu, 29 Jun 2017 18:42:22 +0000 (20:42 +0200)
39 files changed:
arch.communication.tex [new file with mode: 0644]
arch.devices [new file with mode: 0644]
arch.example.tex [new file with mode: 0644]
arch.itasks.tex [new file with mode: 0644]
arch.lift.tex [new file with mode: 0644]
arch.tex [new file with mode: 0644]
conclusion.conclusion.tex [new file with mode: 0644]
conclusion.discussion.tex [new file with mode: 0644]
conclusion.tex
edsl.class.tex [new file with mode: 0644]
edsl.deep.tex [new file with mode: 0644]
edsl.shallow.tex [new file with mode: 0644]
edsl.tex [new file with mode: 0644]
intro.doc.tex [new file with mode: 0644]
intro.intro.tex [new file with mode: 0644]
intro.problem.tex [new file with mode: 0644]
intro.related.tex [new file with mode: 0644]
intro.tex [new file with mode: 0644]
introduction.tex [deleted file]
methods.dsl.tex [deleted file]
methods.mtask.tex [deleted file]
methods.top.tex [deleted file]
mtask.control.tex [new file with mode: 0644]
mtask.examples.tex [new file with mode: 0644]
mtask.expr.tex [new file with mode: 0644]
mtask.io.tex [new file with mode: 0644]
mtask.semantics [new file with mode: 0644]
mtask.tex [new file with mode: 0644]
mtaskext.bytecode.tex [moved from results.mtask.tex with 69% similarity]
mtaskext.examples.tex [new file with mode: 0644]
mtaskext.sdssem.tex [new file with mode: 0644]
mtaskext.tasksem.tex [new file with mode: 0644]
mtaskext.tex [new file with mode: 0644]
results.arch.tex [deleted file]
thesis.tex
top.combinators.tex [new file with mode: 0644]
top.itasks.tex [new file with mode: 0644]
top.sds.tex [new file with mode: 0644]
top.tex [new file with mode: 0644]

diff --git a/arch.communication.tex b/arch.communication.tex
new file mode 100644 (file)
index 0000000..61a7e2e
--- /dev/null
@@ -0,0 +1,165 @@
+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}
diff --git a/arch.devices b/arch.devices
new file mode 100644 (file)
index 0000000..cca4449
--- /dev/null
@@ -0,0 +1,205 @@
+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}
diff --git a/arch.example.tex b/arch.example.tex
new file mode 100644 (file)
index 0000000..4b4f48e
--- /dev/null
@@ -0,0 +1 @@
+Here comes a description of the demo program.
diff --git a/arch.itasks.tex b/arch.itasks.tex
new file mode 100644 (file)
index 0000000..f7fc915
--- /dev/null
@@ -0,0 +1,201 @@
+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}
diff --git a/arch.lift.tex b/arch.lift.tex
new file mode 100644 (file)
index 0000000..1e96bab
--- /dev/null
@@ -0,0 +1,14 @@
+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}
diff --git a/arch.tex b/arch.tex
new file mode 100644 (file)
index 0000000..3e1ea9f
--- /dev/null
+++ b/arch.tex
@@ -0,0 +1,50 @@
+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}
diff --git a/conclusion.conclusion.tex b/conclusion.conclusion.tex
new file mode 100644 (file)
index 0000000..4fde493
--- /dev/null
@@ -0,0 +1,26 @@
+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.
diff --git a/conclusion.discussion.tex b/conclusion.discussion.tex
new file mode 100644 (file)
index 0000000..3b1657f
--- /dev/null
@@ -0,0 +1,113 @@
+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.
index 0cc405e..3f0b3e5 100644 (file)
@@ -1,142 +1,5 @@
 \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}
diff --git a/edsl.class.tex b/edsl.class.tex
new file mode 100644 (file)
index 0000000..aafd355
--- /dev/null
@@ -0,0 +1,57 @@
+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}
diff --git a/edsl.deep.tex b/edsl.deep.tex
new file mode 100644 (file)
index 0000000..fa9d380
--- /dev/null
@@ -0,0 +1,44 @@
+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}
diff --git a/edsl.shallow.tex b/edsl.shallow.tex
new file mode 100644 (file)
index 0000000..b7616b6
--- /dev/null
@@ -0,0 +1,37 @@
+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.
diff --git a/edsl.tex b/edsl.tex
new file mode 100644 (file)
index 0000000..e66577d
--- /dev/null
+++ b/edsl.tex
@@ -0,0 +1,16 @@
+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}
diff --git a/intro.doc.tex b/intro.doc.tex
new file mode 100644 (file)
index 0000000..7350f17
--- /dev/null
@@ -0,0 +1,33 @@
+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}
diff --git a/intro.intro.tex b/intro.intro.tex
new file mode 100644 (file)
index 0000000..3574b58
--- /dev/null
@@ -0,0 +1,51 @@
+\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.
diff --git a/intro.problem.tex b/intro.problem.tex
new file mode 100644 (file)
index 0000000..cfb8494
--- /dev/null
@@ -0,0 +1,10 @@
+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.
diff --git a/intro.related.tex b/intro.related.tex
new file mode 100644 (file)
index 0000000..e2af6e2
--- /dev/null
@@ -0,0 +1,45 @@
+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.
diff --git a/intro.tex b/intro.tex
new file mode 100644 (file)
index 0000000..1a93b40
--- /dev/null
+++ b/intro.tex
@@ -0,0 +1,11 @@
+\section{Introduction}
+\input{intro.intro}
+
+\section{Problem statement}
+\input{intro.problem}
+
+\section{Document structure}
+\input{intro.doc}
+
+\section{Related work}
+\input{intro.related}
diff --git a/introduction.tex b/introduction.tex
deleted file mode 100644 (file)
index 9243d2a..0000000
+++ /dev/null
@@ -1,146 +0,0 @@
-\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.
diff --git a/methods.dsl.tex b/methods.dsl.tex
deleted file mode 100644 (file)
index 9101293..0000000
+++ /dev/null
@@ -1,151 +0,0 @@
-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}
diff --git a/methods.mtask.tex b/methods.mtask.tex
deleted file mode 100644 (file)
index 70cca5b..0000000
+++ /dev/null
@@ -1,238 +0,0 @@
-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}
diff --git a/methods.top.tex b/methods.top.tex
deleted file mode 100644 (file)
index 9d07eec..0000000
+++ /dev/null
@@ -1,209 +0,0 @@
-\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}
diff --git a/mtask.control.tex b/mtask.control.tex
new file mode 100644 (file)
index 0000000..680e10f
--- /dev/null
@@ -0,0 +1,34 @@
+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}
diff --git a/mtask.examples.tex b/mtask.examples.tex
new file mode 100644 (file)
index 0000000..925b66b
--- /dev/null
@@ -0,0 +1,31 @@
+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}
diff --git a/mtask.expr.tex b/mtask.expr.tex
new file mode 100644 (file)
index 0000000..62e9502
--- /dev/null
@@ -0,0 +1,22 @@
+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}
diff --git a/mtask.io.tex b/mtask.io.tex
new file mode 100644 (file)
index 0000000..07eb3ea
--- /dev/null
@@ -0,0 +1,47 @@
+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}
diff --git a/mtask.semantics b/mtask.semantics
new file mode 100644 (file)
index 0000000..2cee3cc
--- /dev/null
@@ -0,0 +1,57 @@
+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}
diff --git a/mtask.tex b/mtask.tex
new file mode 100644 (file)
index 0000000..12bf498
--- /dev/null
+++ b/mtask.tex
@@ -0,0 +1,52 @@
+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}
similarity index 69%
rename from results.mtask.tex
rename to mtaskext.bytecode.tex
index 6ec25a4..111be6f 100644 (file)
@@ -1,68 +1,3 @@
-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
@@ -118,8 +53,8 @@ instance serial ByteCode
 
 \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.
@@ -277,15 +212,15 @@ addSDS sds v s = {s & sdss=[{sds & sdsval=BCValue v}:s.sdss]}
 \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.}]
@@ -333,20 +268,3 @@ toMessages interval x oldstate
 # 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}
diff --git a/mtaskext.examples.tex b/mtaskext.examples.tex
new file mode 100644 (file)
index 0000000..66c2466
--- /dev/null
@@ -0,0 +1,15 @@
+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}
diff --git a/mtaskext.sdssem.tex b/mtaskext.sdssem.tex
new file mode 100644 (file)
index 0000000..5ba33ad
--- /dev/null
@@ -0,0 +1,23 @@
+\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}
diff --git a/mtaskext.tasksem.tex b/mtaskext.tasksem.tex
new file mode 100644 (file)
index 0000000..470a257
--- /dev/null
@@ -0,0 +1,28 @@
+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}
diff --git a/mtaskext.tex b/mtaskext.tex
new file mode 100644 (file)
index 0000000..a8d525f
--- /dev/null
@@ -0,0 +1,20 @@
+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}
diff --git a/results.arch.tex b/results.arch.tex
deleted file mode 100644 (file)
index b934158..0000000
+++ /dev/null
@@ -1,631 +0,0 @@
-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.
index 088549b..9229059 100644 (file)
 \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}
diff --git a/top.combinators.tex b/top.combinators.tex
new file mode 100644 (file)
index 0000000..64aa98a
--- /dev/null
@@ -0,0 +1,54 @@
+\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.
diff --git a/top.itasks.tex b/top.itasks.tex
new file mode 100644 (file)
index 0000000..891fd96
--- /dev/null
@@ -0,0 +1,68 @@
+\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.
+
diff --git a/top.sds.tex b/top.sds.tex
new file mode 100644 (file)
index 0000000..2f30a85
--- /dev/null
@@ -0,0 +1,83 @@
+\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}
diff --git a/top.tex b/top.tex
new file mode 100644 (file)
index 0000000..816f442
--- /dev/null
+++ b/top.tex
@@ -0,0 +1,8 @@
+\section{iTasks}
+\input{top.itasks}
+
+\section{Combinators}
+\input{top.combinators}
+
+\section{Shared Data Sources}
+\input{top.sds}