.
[msc-thesis1617.git] / methods.top.tex
1 \section{iTasks}
2 \gls{TOP} is a novel programming paradigm implemented as
3 \gls{iTasks}~\cite{achten_introduction_2015} in the pure lazy functional
4 language \gls{Clean}~\cite{brus_cleanlanguage_1987}. \gls{iTasks} is an
5 \gls{EDSL} to model workflow tasks in the broadest sense. A \gls{Task} is just
6 a function that --- given some state --- returns the observable \CI{TaskValue}.
7 The \CI{TaskValue} of a \CI{Task} can have different states. Not all state
8 transitions are possible as shown in Figure~\ref{fig:taskvalue}. Once a value
9 is stable it can never become unstable again. Stability is often reached by
10 pressing a confirmation button. \glspl{Task} yielding a constant value are
11 immediately stable.
12
13 A simple \gls{iTasks} example illustrating the route to stability of a
14 \gls{Task} in which the user has to enter a full name is shown in
15 Listing~\ref{lst:taskex}. The code is accompanied by screenshots showing the
16 user interface in Figure~\ref{fig:taskex1},~\ref{fig:taskex2}
17 and~\ref{fig:taskex3}. The \CI{TaskValue} of the \gls{Task} is in the first
18 image in the \CI{NoValue} state, the second image does not have all the fields
19 filled in and therefore the \CI{TaskValue} remains \CI{NoValue}. In the third
20 image all fields are entered and the \CI{TaskValue} transitions to the
21 \CI{Unstable} state. When the user presses \emph{Continue} the value becomes
22 \CI{Stable} and cannot be changed any further.
23
24 \begin{figure}[H]
25 \centering
26 \includegraphics[width=.5\linewidth]{fig-taskvalue}
27 \caption{The states of a \CI{TaskValue}}\label{fig:taskvalue}
28 \end{figure}
29
30 \begin{lstlisting}[label={lst:taskex},%
31 caption={An example \gls{Task} for entering a name}]
32 :: Name = { firstname :: String
33 , lastname :: String
34 }
35
36 derive class iTask Name
37
38 enterInformation :: String [EnterOption m] -> (Task m) | iTask m
39
40 enterName :: Task Name
41 enterName = enterInformation "Enter your name" []
42 \end{lstlisting}
43
44 \begin{figure}[H]
45 \centering
46 \begin{subfigure}{.25\textwidth}
47 \centering
48 \includegraphics[width=.9\linewidth]{taskex1}
49 \caption{Initial interface}\label{fig:taskex1}
50 \end{subfigure}
51 \begin{subfigure}{.25\textwidth}
52 \centering
53 \includegraphics[width=.9\linewidth]{taskex2}
54 \caption{Incomplete entrance}\label{fig:taskex2}
55 \end{subfigure}
56 \begin{subfigure}{.25\textwidth}
57 \centering
58 \includegraphics[width=.9\linewidth]{taskex3}
59 \caption{Complete entry}\label{fig:taskex3}
60 \end{subfigure}
61 \caption{Example of a generated user interface}
62 \end{figure}
63
64 For a type to be suitable, it must have instances for a collection of generic
65 functions that is captured in the class \CI{iTask}. Basic types have
66 specialization instances for these functions and show an interface accordingly.
67 Derived interfaces can be modified with decoration operators or specializations
68 can be created.
69
70 \section{Combinators}
71 \Glspl{Task} can be combined using so called \gls{Task}-combinators.
72 Combinators describe relations between \glspl{Task}. There are only two basic
73 types of combinators; parallel and sequence. All other combinators are
74 derived from the basic combinators. Type signatures of simplified versions of
75 the basic combinators and their derivations are given in
76 Listing~\ref{lst:combinators}
77
78 \begin{lstlisting}[%
79 caption={\Gls{Task}-combinators},label={lst:combinators}]
80 //Step combinator
81 (>>=) infixl 1 :: (Task a) (a -> Task b) -> Task b | iTask a & iTask b
82 (>>*) infixl 1 :: (Task a) [TaskCont a (Task b)] -> Task b | iTask a & iTask b
83 :: TaskCont a b
84 = OnValue ((TaskValue a) -> Maybe b)
85 | OnAction Action ((TaskValue a) -> Maybe b)
86 | E.e: OnException (e -> b) & iTask e
87 | OnAllExceptions (String -> b)
88 :: Action = Action String
89
90 //Parallel combinators
91 (-||-) infixr 3 :: (Task a) (Task a) -> Task a | iTask a
92 (||-) infixr 3 :: (Task a) (Task b) -> Task b | iTask a & iTask b
93 (-||) infixl 3 :: (Task a) (Task b) -> Task a | iTask a & iTask b
94 (-&&-) infixr 4 :: (Task a) (Task b) -> Task (a,b) | iTask a & iTask b
95 \end{lstlisting}
96
97 \paragraph{Sequence:}
98 The implementation for the sequence combinator is called the
99 \CI{step} (\CI{>>*}). This combinator runs the left-hand \gls{Task} and
100 starts the right-hand side when a certain predicate holds. Predicates
101 can be propositions about the \CI{TaskValue}, user actions from within
102 the web browser or a thrown exception. The familiar
103 bind-combinator is an example of a sequence combinator. This combinator
104 runs the left-hand side and continues to the right-hand \gls{Task} if
105 there is an \CI{UnStable} value and the user presses continue or when
106 the value is \CI{Stable}. The combinator could have been implemented
107 as follows:
108 \begin{lstlisting}[language=Clean]
109 (>>=) infixl 1 :: (Task a) (a -> (Task b)) -> (Task b) | iTask a & iTask b
110 (>>=) ta f = ta >>* [OnAction "Continue" onValue, OnValue onStable]
111 where
112 onValue (Value a _) = Just (f a)
113 onValue _ = Nothing
114
115 onStable (Value a True) = Just (f a)
116 onStable _ = Nothing
117 \end{lstlisting}
118
119 \paragraph{Parallel:}
120 The parallel combinator allows for concurrent \glspl{Task}. The
121 \glspl{Task} combined with these operators will appear at the same time
122 in the web browser of the user and the results are combined as the type
123 dictates. All parallel combinators used are derived from the basic parallel
124 combinator that is very complex and only used internally.
125
126 \section{Shared Data Sources}
127 \Glspl{SDS} are an abstraction over resources that are available in the world
128 or in the \gls{iTasks} system. The shared data can be a file on disk, the
129 system time, a random integer or just some data stored in memory. The actual
130 \gls{SDS} is just a record containing functions on how to read and write the
131 source. In these functions the \CI{*IWorld} --- which in turn contains the real
132 \CI{*World} --- is available. Accessing the outside world is required for
133 interacting with it and thus the functions can access files on disk, raw
134 memory, other \glspl{SDS} and hardware.
135
136 The basic operations for \glspl{SDS} are get, set and update. The signatures
137 for these functions are shown in Listing~\ref{lst:shares}. By default, all
138 \glspl{SDS} are files containing a \gls{JSON} encoded version of the object and
139 thus are persistent between restarts of the program. Library functions for
140 shares residing in memory are available as well. The three main operations on
141 shares are atomic in the sense that during reading no other \glspl{Task} are
142 executed. The system provides useful functions to transform, map and combine
143 \glspl{SDS} using combinators. The system also provides functionality to
144 inspect the value of an \gls{SDS} and act upon a change. \Glspl{Task} waiting on
145 an \gls{SDS} to change are notified when needed. This results in low resource
146 usage because \glspl{Task} are never constantly inspecting \gls{SDS} values but
147 are notified.
148
149 \begin{lstlisting}[%
150 label={lst:shares},caption={\Gls{SDS} functions}]
151 :: RWShared p r w = ...
152 :: ReadWriteShared r w :== RWShared () r w
153 :: ROShared p r :== RWShared p () r
154 :: ReadOnlyShared r :== ROShared () r
155
156 :: Shared r :== ReadWriteShared r r
157
158 get :: (ReadWriteShared r w) -> Task r | iTask r
159 set :: w (ReadWriteShared r w) -> Task w | iTask w
160 upd :: (r -> w) (ReadWriteShared r w) -> Task w | iTask r & iTask w
161
162 sharedStore :: String a -> Shared a | JSONEncode{|*|}, JSONDecode{|*|}
163 \end{lstlisting}
164
165 \section{Parametric Lenses}
166 \Glspl{SDS} can contain complex data structures such as lists, trees and even
167 resources in the outside world. Sometimes, an update action only updates a part
168 of the resource. When this happens, all waiting \glspl{Task} looking at the
169 resource are notified of the update. However, it may be the case that
170 \glspl{Task} were only looking at parts of the structure that was not updated.
171 To solve this problem, parametric lenses were
172 introduced~\cite{domoszlai_parametric_2014}.
173
174 Parametric lenses add a type variable to the \gls{SDS}. This type variable is
175 fixed to the void type (i.e. \CI{()}) in the given functions. When an \gls{SDS}
176 executes a write operation, it also provides the system with a notification
177 predicate. This notification predicate is a function \CI{p -> Bool} where
178 \CI{p} is the parametric lens type. This allows programmers to create a big
179 \gls{SDS}, and have \glspl{Task} only look at parts of the big \gls{SDS}. This
180 technique is used in the current system in memory shares. The \CI{IWorld}
181 contains a map that is accessible through an \gls{SDS}. While all data is
182 stored in the map, only \glspl{Task} looking at a specific entry are notified
183 when the structure is updated. The type of the parametric lens is the key in
184 the map.
185
186 Functionality for setting parameters is available in the system. The most
187 important functions are the \CI{sdsFocus} and the \CI{sdsLens} function. These
188 functions are listed in Listing~\ref{lst:focus}. \CI{sdsFocus} allows the
189 programmer to fix a parametric lens value. \CI{sdsLens} is a kind of
190 \CI{mapReadWrite} including access to the parametric lens value. This allows
191 the creation of, for example, \glspl{SDS} that only read and write to parts of
192 the original \gls{SDS}.
193
194 \begin{lstlisting}[label={lst:focus},
195 caption={Parametric lens functions}]
196 sdsFocus :: p (RWShared p r w) -> RWShared p` r w | iTask p
197
198 :: SDSNotifyPred p :== p -> Bool
199
200 :: SDSLensRead p r rs = SDSRead (p -> rs -> MaybeError TaskException r)
201 | SDSReadConst (p -> r)
202 :: SDSLensWrite p w rs ws = SDSWrite (p -> rs -> w -> MaybeError TaskException (Maybe ws))
203 | SDSWriteConst (p -> w -> MaybeError TaskException (Maybe ws))
204 :: SDSLensNotify p w rs = SDSNotify (p -> rs -> w -> SDSNotifyPred p)
205 | SDSNotifyConst (p -> w -> SDSNotifyPred p)
206
207 sdsLens :: String (p -> ps) (SDSLensRead p r rs) (SDSLensWrite p w rs ws) (SDSLensNotify p w rs)
208 (RWShared ps rs ws) -> RWShared p r w | iTask ps
209 \end{lstlisting}