\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 \glspl{mTask} 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.
+\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.
\paragraph{Optimizing the interpreter:}
Due to time constraints and focus, hardly any work has been done in the
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 \glspl{mTask} for
+\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.
be connected through various means of communication such as serial port,
bluetooth, wifi and wired network communication. The bytecode on the devices is
interpreted using a stack machine and provides the programmer interfaces
-to the peripherals. The semantics of the \glspl{mTask} tries to resemble the
+to the peripherals. The semantics for \gls{mTask} tries to resemble the
\gls{iTasks} semantics as close as possible.
The host language has a proven efficient compiler and code generator. Therefore,
-compiling \glspl{mTask} is also fast. Compiling \glspl{mTask} is nothing
-more than running some functions native to the host language.
+compiling \gls{mTask}-\glspl{Task} is also fast. Compiling an
+\gls{mTask}-\gls{Task} is nothing more than running some functions native to
+the host language.
The dynamic nature allows the microcontroller to be programmed once and used
many times. The program memory of microcontrollers often guarantees around
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
+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.
(=.) infixr 2 :: (v t Upd) (v t p) -> v t Expr | ...
\end{lstlisting}
-One way of storing data in \glspl{mTask} 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
+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}.
\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
-\glspl{mTask} according to certain rules and semantics.
+\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
\end{lstlisting}
\section{Example mTask}
-Some example \glspl{mTask} using almost all of their functionality are shown in
-Listing~\ref{lst:exmtask}. The \glspl{mTask} 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.
+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 \glspl{mTask}}]
+ 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)
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 a \gls{SDS} and act upon a change. \Glspl{Task} waiting on
-a \gls{SDS} to change are notified when needed. This results in low resource
+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.
\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 a \gls{SDS}. While all data is
+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.
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 \glspl{mTask} --- 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 \glspl{mTask} 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
+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:
\glspl{SDS} and the size of the stack.
\begin{lstlisting}[label={lst:devicespec},
- caption={Device specification for \glspl{mTask}}]
+ caption={Device specification for \gls{mTask}-\glspl{Task}}]
:: MTaskDeviceSpec =
{ haveLed :: Bool
, haveLCD :: Bool
\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 a \gls{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
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 a \gls{SDS} is written,
+\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}.
\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 share that heavily depends on parametric
+be solved by using a tailor made \gls{SDS} that heavily depends on parametric
lenses.
\subsection{Parametric Lenses}
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 a \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 a \gls{SDS}
+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.
$ sdsFocus (Just (d, -1)) deviceStore
\end{lstlisting}
-\subsubsection{Local-share specific \glspl{SDS}}
+\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 share and
-uses the \CI{mapReadWrite} functions to serve the correct part of the
+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}}]
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 \glspl{mTask} are of the type \CI{Task (Main (ByteCode
-() Stmt))} and can thus ask for user input first if needed for parameterized
-\glspl{mTask}. 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.
+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
\end{figure}
\section[Lifting mTasks to iTasks-Tasks]%
- {Lifting \glspl{mTask} to \gls{iTasks}-\glspl{Task}}
+ {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}-\glspl{Task}. The function is called with a name, \gls{mTask},
-The \glspl{Task} suitable for a client are called \glspl{mTask} 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.
+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
\end{lstlisting}
\section{Bytecode compilation view}\label{sec:compiler}
-The \glspl{mTask} 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
+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
shown in Listing~\ref{lst:bcview}, the \CI{ByteCode} view is a boxed \gls{RWST}
that writes bytecode instructions (\CI{BC}, Subsection~\ref{sec:instruction})
while carrying around a \CI{BCState}. The state is kept between compilations
noOp = tell` [BCNop]
\end{lstlisting}
-The semantics for the \glspl{mTask} bytecode view are different from the
-semantics of the \gls{C} view. \glspl{Task} in the \gls{C} view can start new
-\glspl{Task} or even start themselves to continue, while in the bytecode view,
-\glspl{Task} run indefinitly, one-shot or on interrupt. To allow interval and
-interrupt \glspl{Task} to terminate, a return instruction is added. This class
-was not available in the original system and is thus added. It just writes a
-single instruction so that the interpreter knows to stop execution.
+The semantics for the \gls{mTask}-\glspl{Task} bytecode view are different from
+the semantics of the \gls{C} view. \glspl{Task} in the \gls{C} view can start
+new \glspl{Task} or even start themselves to continue, while in the bytecode
+view, \glspl{Task} run indefinitly, one-shot or on interrupt. To allow interval
+and interrupt \glspl{Task} to terminate, a return instruction is added. This
+class was not available in the original system and is thus added. It just
+writes a single instruction so that the interpreter knows to stop execution.
Listing~\ref{lst:return} shows the classes and implementation for the return
expression.
\end{lstlisting}
All assignable types compile to a \gls{RWST} which writes the specific fetch
-instruction(s). For example, using a \gls{SDS} always results in an expression
+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
\chapter{Embedded Domain Specific Languages}\label{chp:dsl}
\input{methods.dsl}
-\chapter[The mTask EDSL]{The \gls{mTask} \gls{EDSL}}\label{chp:mtask}
+\chapter[The mTask-EDSL]{The \gls{mTask}-\gls{EDSL}}\label{chp:mtask}
\input{methods.mtask}
\chapter[Extending the mTask EDSL]{Extending the \gls{mTask} {EDSL}}\label{chp:mtaskcont}