i-Tasks
-
Generating Multi-User Workflow Systems
for the WWWeb
With Clean’s
new i-Tasks library you can generate a
multi-user workflow system for the web.
It makes use of the i-Data library
with which web forms can be
generated and handled automatically given a static type of a
data structure.
These Clean libraries
use generic programming
techniques which enables a very compact and concise notation.
DOWNLOAD INSTRUCTIONS
If
you want to use i-Tasks you
More
information:
Have a look at the DEMO’s and the
corresponding CLEAN CODE:
Below
we give a short idea about what i-Tasks are. More examples are given in the DEMO page.
i-Tasks:
generating an editor for any (first
order) type
Here follows the
code of a complete i-Tasks application written in Clean:
module example
import StdEnv, StdHtml
Start world = doHtmlServer
(singleUserTask 0 True simple) world
simple :: (Task Int)
simple = editTask "Done" createDefault
The first two lines are standard, the
third lines is the main function. It automatically links in an http server (doHtmlServer ) for easy testing of a user defined web application
defined by the function simple.
This function uses the basic i-Tasks editor
editTask. It can generate an html form editor for any type.
The editor does need an initial value of this type. But in this case a default
value (0) is generated by createDefault.
The function createDefault can create a default value for any first order type. With the button "Done" the user can indicate that the i-Task editor is
finished. This example generates the following web page in which repeatedly an
Integer value can be typed in until the "Done" button is pressed.
Only Integer values will be accepted by
the application, because the type of simple is (Task
Int). By only changing the type of the function simple a
different form is generated, e.g. if the type is changed into (Task (Int, Real))
one obtains a box for typing in an Integer and a Real value:
simple :: (Task (Int, Real))
simple = editTask "Done" createDefault
This works for any
first order type one can define in Clean (algebraic data types such as lists,
trees, for types like arrays and records), hence for user defined types as
well. For instance for record types:
:: Person = { name ::
String
, street ::
String
, number ::
Int
, zipCode ::
String
, town ::
String
, born ::
HtmlDate
}
simple
simple = editTask "Done" createDefault
derive
gForm Person; derive gUpd
Person; derive gParse Person; derive gPrint Person; derive gerda Person;
For a user defined type one has to ask the compiler to
derive instances for the generic functions that are being used to generate,
store and handle web forms:
i-Tasks:
combining tasks
Monads are used (yes, we have them in Clean, and
they are type safe thanks to Clean’s uniqueness
typing) for sequencing i-Tasks. For instance
if one want to type in two Integers in a sequence and add up their values, one
defines:
simple :: (Task Int)
simple
= editTask "Done" createDefault
=>>
\v1 -> editTask "Done" createDefault
=>>
\v2 -> [Txt
"+", Hr [] ]
!>> return_D
(v1 + v2)
First an integer value is asked from the user
returning the value v1, then another one is asked returning the
value v2, then some html code is printed [Txt "+", Hr [] ] and the sum of these two values is
returned and printed return_D
(v1 + v2). Notice that the
code of an i-Tasks application
is very easy to read, certainly for functional programmers. The reason is the following.
Although the application is started from scratch every time a new event is
received from the client, it remembers its state and finds its way back to the
point where it was handling tasks the previous time. So the programmer can read
the code “line by line” although it is not executed in this way at
all. The application remembers which tasks are finished and which tasks still
have to be done. Another reason for the simplicity of the code is that almost
all information is saved and retrieved automatically. Information can be stored
in html pages, in files or in a relational database just by changing an option.
The library offers many
combinators for handling tasks, such as:
In fact, all workflow patterns as
they are commonly can be found in commercial workflow systems are supported.
But there are many
advantages over many commercial systems.
To see more complicated
examples: goto
the demo page.
i-Tasks:
multi-user tasks
Tasks can be assigned to different users. Each user
has a unique id. This id can be assigned (@::) to any task or any
combination of tasks.
For instance in our simple example we can specify that the first number has
to be given by user 1, the second by user 2, the result is shown to the default user (which is user 0).
simple :: (Task Int)
simple
= 1 @:: editTask "Done" createDefault
=>>
\v1 -> 2 @:: editTask "Done" createDefault
=>>
\v2 -> [Txt
"+", Hr [] ]
!>>
return_D (v1 + v2)
So, all participants in an i-Task workflow application work with one and the
same application. This makes it relatively easy to reason about the
system. The system can deal with multiple users and will show
to each user only the part of the information which is intended for him or her.
Login scenario’s can be programmed as an i-Task as well.
To see more complicated
examples: goto
the demo page.