Title: i-Tasks - interactive workflow Tasks for the WWWEB ___________
1i-Tasks-interactive workflow Tasksfor the
WWWEB___________
Rinus Plasmeijer University of Nijmegen www.cs.r
u.nl/clean
2Clean
- Introduction
- Defining Interactive Multi-user Workflow Systems
for the web - Defining a simple task an editor for a web form
- Combinators for constructing tasks
- Assigning tasks to users
- Logging in to a Multi-user Workflow System
- Implementation
- Basic idea of generic programming
- Generic functions for handling web forms i-Data
- Implementation of i-Tasks
- Conclusion Future Research
3Clean
- Introduction
- Defining Interactive Multi-user Workflow Systems
for the web - Defining a simple task an editor for a web form
- Combinators for constructing tasks
- Assigning tasks to users
- Logging in to a Multi-user Workflow System
- Implementation
- Basic idea of generic programming
- Generic functions for handling web forms i-Data
- Implementation of i-Tasks
- Conclusion Future Research
4Clean
- State-Of-The-Art Pure Functional Programming
Language - Lazy, pure, higher order functions and types,
lots of features - Clean is an extended subset of Haskell
de-facto standard (GHC) - Haskell is an extended subset of Clean
- Extra facilities in Clean
- I/O Uniqueness Typing lt-gt Monads
- Re-usage Generic programming included lt-gt
Generic Haskell preprocessor - Hybrid typing Static as well as Dynamic typing
lt-gt poor man's Dynamics - Type safe plug-inns run-time storing and loading
of functions - Sparkle Cleans dedicated theorem prover
- Gast Cleans test system
- Clean Compiler is fast (4th place language
shootout, after 3 C compilers !) - 2 third party Haskell -gt Clean compilers
- Haskell / Clean code can be combined in next
Clean release
5Why workflows?
- Dutch STW grant Demand Driven Workflows
- New approach on specifying workflows making use
of "lazy evaluation" -
- University TU Eindhoven (Van der Aalst)
- RadBoud University Nijmegen (Plasmeijer)
- Industry Palas Athena (Eindhoven) producer of
commercial workflow system - ABZ (Utrecht) uses workflow system for
developing applications - AIA (Nijmegen) produces content management
systems - i -Tasks
- First, "simple" approach to make a quick start
- Already offers more functionality than found in
commercial systems - i Tasks Executable Specifications of
Interactive Workflow Systems for the
Web,R.Plasmeijer, P.Achten, P.Koopman, ICFP
2007. - see http//www.cs.ru.nl/rinus/iTaskIntro.html
6i -Tasks Approach I
- Study Workflow Patterns (Van der Aalst, ter
Hofstede, Kiepuszewski, Barros) - gt 30 products Staffware, Cosa, InConcert,
Eastman Software, FLOWer, Domino Workflow,
Meteor, Mobile, MQSeries, Forte Conductor,Verve,
Visual WorkFlo, Changengine, I-Flow, SAP R/3
Workflow - patterns sequence, recursion, exclusive choice,
multiple choice, split/merge (parallel or,
parallel and, discriminator), ... - All Workflow Patterns can "straightforwardly" be
implemented in Clean - Using i-Data Clean library for handling
interactive web forms - Using generic functions highly reusable
functions, given a type they - generate an html form
- deal with any change made by a user in a form
- enable separation between model (value returned)
and view (the looks) - automatically store and retrieve info in a file
or database
7i -TasksApproach II
- Disadvantages i Tasks over Commercial Systems
- No nice graphical interface for defining
workflows just Clean code - A first prototype, limited interfaces to real
world, lots of additional wishes - Advantages i Tasks over Commercial Systems
-
- Declarative, executable specification
- Workflows are statically typed, input type
checked as well - Highly reusable code polymorphic, overloaded,
generic - Workflows are dynamically constructed
- Flow can depend on the actual contents
- Fully compositional
- Higher order tasks shift work flows to someone
else - It generates a multi-user web enabled (!)
workflow system - lt 1000 lines of code based on Cleans i-Data
library for the web
8i -Tasks Approach III
- Web applications are not easy to write
- Interactive applications for the Web are hard to
programme - No direct connection between User on Client lt--gt
Application on Server - Web has no notion of state application has to
store information - Multi-user applications even harder
- Offer a layer which hides as many annoying
details as possible. - i Tasks - Embedded Domain Specific Language
- Workflow Specification Language which generates
a multi-user system for the web. - i Tasks Workflow Combinator Library for Clean
9Clean
- Introduction
- Defining Interactive Multi-user Workflow Systems
for the web - Defining a simple task an editor for a web form
- Combinators for constructing tasks
- Assigning tasks to users
- Logging in to a Multi-user Workflow System
- Implementation
- Basic idea of generic programming
- Generic functions for handling web forms i-Data
- Implementation of i-Tasks
- Conclusion Future Research
10A very small complete example I
- module example
- import StdEnv, StdHtml
- Start world doHtmlServer (singleUserTask 0 True
simple) world - simple (Task Int)
- simple editTask "Done" createDefault
11Testing an i Tasks application
Changes in Forms
Htmlcode
Clean Application
12Final setting of an i Tasks application
Changes in Forms
Htmlcode
13A very small complete example II
- module example
- import StdEnv, StdHtml
- Start world doHtmlServer (singleUserTask 0 True
simple) world - simple (Task (Int, Real))
- simple editTask "Done" createDefault
14A very small complete example III
- simple (Task Int)
- simple editTask "Done" createDefault
15A very small complete example IV
- Person name String
- , street String
- , number Int
- , zipCode String
- , town String
- , born HtmlDate
-
- simple (Task Person)
- simple editTask "Done" createDefault
- derive gForm Person
- derive gUpd Person
- derive gParse Person
- derive gPrint Person
- derive gerda Person
16editTask
- editTask String a ? (Task a) iData a // an
editor for values of type "a" - Task a // an interactive task
- A task consist of an amount of work to be
performed by the user involving 0 interactions - It is either not active, active, or finished.
17editTask uses generic functions
- class iData a gForm , iCreateAndPrint,
iParse, iSpecialStore a - class iCreateAndPrint a iCreate, iPrint a
- class iCreate a gUpd a
- class iPrint a gPrint a
- class iParse a gParse a
- class iSpecialStore a gerda , TC a
- It requires the instantiation of several generic
functions for type "a" e.g. - gForm html form creation,
- gUpd form handling,
- gParse parsing,
- gPrint printing,
- gerda data storage I a relational database,
- TC Conversion to and from Dynamics, option used
to store functions -
- which can all, on request, automatically be
derived by the compiler !
18Options
- A task or combination of tasks, can have several
options - class (ltlt_at_) infixl 3 b (Task a) b ? Task a
- instance ltlt_at_ Lifespan // default Session
- , StorageFormat // default PlainString
- , Mode // default Edit
- , GarbageCollect // deafult Collect
- Lifespan Database TxtFile Session Page
Temp - StorageFormat StaticDynamic PlainString
- Mode Edit Submit Display NoForm
- GarbageCollect Collect NoCollect
-
19A very small complete example IV
- simple (Task Person)
- simple editTask "Done" createDefault
20A very small complete example IV Submit
- simple (Task Person)
- simple editTask "Done" createDefault ltlt_at_ Submit
21A very small complete example IV, Submit,
Database
- simple (Task Person)
- simple editTask "Done" createDefault ltlt_at_ Submit
ltlt_at_ Database
22A very small complete example IV, Submit,
TxtFile
- simple (Task Person)
- simple editTask "Done" createDefault ltlt_at_ Submit
ltlt_at_ TxtFile
23Clean
- Introduction
- Defining Interactive Multi-user Workflow Systems
for the web - Defining a simple task an editor for a web form
- Combinators for constructing tasks
- Assigning tasks to users
- Logging in to a Multi-user Workflow System
- Implementation
- Basic idea of generic programming
- Generic functions for handling web forms i-Data
- Implementation of i-Tasks
- Conclusion Future Research
24Sequencing of tasks
- Sequencing / composition of tasks (monadic
style) - (gtgt) infix 1 (Task a) (a ? Task b) ? Task
b - (gtgt) infixl 1 (Task a) (Task b) ? Task b
- Returning plain values as a Task value
- return_V a ? Task a iData a
-
25Prompting
- Returning plain values as a Task value (showing
the returned value) - return_D a ? Task a iData a
- Prompting as long as / as soon as a task is
activated - (?gtgt) infix 5 BodyTag (Task a) ? Task
a iData a - (!gtgt) infix 5 BodyTag (Task a) ? Task
a iData a -
26Html code
- A Clean Algebraic Data Type (ADT) is defined
isomorphic with Html Code - Provides a grammar only allowing syntactic
"correct" html code - Type error otherwise
- A generic function is used to generate Html code
out of it - BodyTag
- A A_Attr BodyTag // link ancor ltagtlt/agt
- Abbr Std_Attr String // abbreviation
ltabbrgtlt/abbrgt - Acronym Std_Attr String // acronym
ltacronymgtlt/acronymgt - Address Std_Attr String // address
ltaddressgtlt/addressgt - Applet Applet_Attr String // applet
ltappletgtlt/appletgt - Area Area_Attr // link area in an image
ltareagt - B Std_Attr String // bold ltbgtlt/bgt
-
- Txt String // plain text
- U Std_Attr String // underlined text
ltugtlt/ugt - Ul Ul_Attr BodyTag // unordered list
ltulgtlt/ulgt - Var Std_Attr String // variable text
ltvargtlt/vargt
27Sequence of iTasks
- sumInt (Task Int)
- sumInt
- editTask "Done" createDefault
- gtgt \v1 ? editTask "Done" createDefault
- gtgt \v2 ? Txt "", Hr
- !gtgt return_D (v1 v2)
28Simple Coffeemachine (1/3)
29Simple Coffeemachine (2/3)
- simpleCoffee foreverTask SimlpeCoffeeMachine
- SimlpeCoffeeMachine (Task String)
- SimlpeCoffeeMachine
- Txt "Choose product",Br,Br
- ?gtgt chooseTask
- ("Coffee", return_V ("Coffee"))
- , ("Tea", return_V ("Tea"))
-
- gtgt \product ? Txt ("Enjoy your " lt
product) - ?gtgt chooseTask
- "OK, return_V product
-
30Simple Coffeemachine (3/3)
- simpleCoffee foreverTask SimlpeCoffeeMachine
- SimlpeCoffeeMachine (Task String)
- SimlpeCoffeeMachine
- Txt "Choose product",Br,Br
- ?gtgt chooseTask
- ("Coffee", return_V ("Coffee"))
- , ("Tea", return_V ("Tea"))
-
- gtgt \product ? Txt ("Enjoy your " lt
product) - ?gtgt buttonTask "OK" (return_V product)
-
31All kinds of task combinators
- Loop
- foreverTask (Task a) ? (Task a) iData a
- Choose 1 out of n
- chooseTask (String,Task a) ? (Task a)
iData a - Choose m out of n
- mchoiceTasks (String,Task a) ? (Task
a) iData a - Or task, do all in any order, finish as soon as
one completes - (--) infixr 3 (Task a) (Task a) ? (Task a)
iData a - orTasks (String,Task a) ? (Task a)
iData a - And task, do all in any order, and finish when
all completed - (--) infixr 4 (Task a) (Task b) ? (Task
(a,b)) iData a iData b - andTasks (String,Task a) ? (Task a)
iData a - Treat user defined function as a new task
enables recursion - newTask String (Task a) ? (Task a)
iData a
32Coffeemachine (1/3)
33Coffeemachine (2/3)
- infCoffee foreverTask CoffeeMachine
- CoffeeMachine Task (String, Int)
- CoffeeMachine
- Txt "Choose product", Br, Br
- ?gtgt chooseTask
- ("Coffee 100", return_V (100,"Coffee"))
- , ("Cappucino 150", return_V
(150,"Cappucino")) - , ("Tee 50", return_V (50, "Tee"))
- , ("Choclate 100", return_V
(100,"Choclate")) -
- gtgt \(toPay, product) ?Txt ("Chosen product "
lt product), Br, Br - ?gtgt getCoins (toPay, 0)
- gtgt \(cancel, returnMoney)
- ? let nproduct if cancel
"Cancelled" product in - Txt ("product " lt nproduct lt ",
- returned money " lt returnMoney), Br,
Br - ?gtgt buttonTask "Thanks" (return_V (nproduct,
returnMoney)) -
34Coffeemachine (3/3)
- getCoins (Int, Int) -gt Task (Bool, Int)
- getCoins (toPay, paid) newTask "getCoins"
getCoins - where
- getCoins
- Txt ("To pay " lt toPay), Br, Br
- ?gtgt chooseTask (c gt " cts", return_V
(False, c)) \\ c ? coins - --
- buttonTask "Cancel" (return_V (True, 0))
- gtgt handleMoney
- handleMoney (cancel, coin)
- cancel return_V (True, paid)
- toPay - coin gt 0 getCoins (toPay - coin,
paid coin) - otherwise return_V (False, coin - toPay)
- coins 5, 10, 20, 50, 100, 200
-
35Clean
- Introduction
- Defining Interactive Multi-user Workflow Systems
for the web - Defining a simple task an editor for a web form
- Combinators for constructing tasks
- Assigning tasks to users
- Logging in to a Multi-user Workflow System
- Implementation
- Basic idea of generic programming
- Generic functions for handling web forms i-Data
- Implementation of i-Tasks
- Conclusion Future Research
36Multi-user combinators
- Multi-user
- (_at_) infix 3 (String, Int) (Task a) ? (Task
a) iData a - (_at_) infix 3 Int (Task a) ? (Task a)
iData a -
37Multi-User example Review Task
38Multi-User example Review Task
39Review Task (1/3)
- Review Approved Cancelled NeedsRework
TextArea Draft - reviewTask a ? (Task Review) iData a
- reviewTask v
- toHtml v, Br, Br
- ?gtgt chooseTask
- ("Rework", editTask "Done" (NeedsRework
createDefault) ltlt_at_ Submit) - , ("Approved", return_V Approved)
- , ("Reject", return_V Rejected)
-
40Review Task (2/3)
- taskToReview Int (a, a ? Task a) ? Task (a,
Review) iData a - taskToReview reviewer (val, task)
- newTask "taskToReview" taskToReview
- where
- taskToReview
- task val
- gtgt \newval ? reviewer _at_ reviewTask newval
- gtgt \review ? Txt ("Reviewer " lt reviewer
lt " says ") , toHtml review, Br - ?gtgt editTask "OK" Void
- gtgt case review of
- (NeedsRework _) ? taskToReview reviewer
(newval, task) - else ? return_V
(newval, review) -
41Review Task (3/3)
- QForm toComp String
- , startDate HtmlDate
- , endDate HtmlDate
- , estimatedHours Int
- , description TextArea
- , price Real
-
- startTask Task (QForm, Review)
- startTask taskToReview 1 (createDefault,
mytask) - mytask a ? (Task a) iData a
- mytask v Txt "Fill in Form", Br, Br
- ?gtgt editTask "TaskDone" v ltlt_at_ Submit
42Higher-Order Tasks
- Tasks not only deliver values, they may deliver a
task under development ! - TClosure a TClosure (Task a)
- Maybe a Just a Nothing
- orTask variant a task is either finished, or
interrupted if the stop task is finished sooner - (-!gt) infix 4 (Task stop) (Task a) ? (Task
(Maybe stop, TClosure a)) iData stop iData a
43Multi-User example delegate a task
44Delegate a Task
- delegateToSomeone Int (Task a) Int ? (Task
a) iData a - delegateToSomeone me task set newTask
"delegateToSomeone" doDelegate - where
- doDelegate
- orTasks ("Waiting for " lt who
- , who _at_ chooseTask ("I Will Do It,
return_V who) - ) \\ who ? set
-
- gtgt \volunteer ? volunteer _at_ stopIt -!gt task
- gtgt \(stopped, TClosure task) ?
- if (isJust stopped) (delegateToSomeone me
task set) task -
- stopIt stop -- (me _at_ stop)
- stop chooseTask ("Stop, return_V
True)
45Clean
- Introduction
- Defining Interactive Multi-user Workflow Systems
for the web - Defining a simple task an editor for a web form
- Combinators for constructing tasks
- Assigning tasks to users
- Logging in to a Multi-user Workflow System
- Implementation
- Basic idea of generic programming
- Generic functions for handling web forms i-Data
- Implementation of i-Tasks
- Conclusion Future Research
46Login handling types and functions
- Accounts s Account s
- Account s login Login // login
info - , uniqueId Int // unique identifier
- , state s // state
-
- Login loginName String // Should be
unique - , password PasswordBox // Should remain
secret -
- Maybe a Just a Nothing
- addAccount (Account s) (Accounts s) ?
(Accounts s) - removeAccount (Account s) (Accounts s) ?
(Accounts s) - changeAccount (Account s) (Accounts s) ?
(Accounts s) - hasAccount Login (Accounts s) ? (Maybe
(Account s)) - invariantLogins String Login ? Maybe
(String,String)
47iTasks can be used for persistent storage of
information
- definition module iTaskDB
- import iTasks
- DBid a
- mkDBid String Lifespan ? (DBid a)
- readDB (DBid a) ? Task a iData a
- writeDB (DBid a) a ? Task a iData a
-
48Creating a database for a login accounts
- accountId DBid (Accounts a)
- accountId mkDBid "loginAccount" TxtFile
- readAccountsDB (Task (Accounts a)) iData a
- readAccountsDB readDB accountId
- addAccountsDB (Account a) (Accounts a) ? (Task
(Accounts a)) iData a - addAccountsDB acc accs writeDB accountId
(addAccount acc accs) -
49Creating a database for a login accounts
- accountId DBid (Accounts a)
- accountId mkDBid "loginAccount" Database
- readAccountsDB (Task (Accounts a)) iData a
- readAccountsDB readDB accountId
- addAccountsDB (Account a) (Accounts a) ? (Task
(Accounts a)) iData a - addAccountsDB acc accs writeDB accountId
(addAccount acc accs) -
50Creating a database for a login accounts
- Void Void
- accountId DBid (Accounts Void)
- accountId mkDBid "loginAccount" TxtFile
- readAccountsDB (Task (Accounts Void))
- readAccountsDB readDB accountId
- addAccountsDB (Account Void) (Accounts Void) ?
(Task (Accounts Void)) - addAccountsDB acc accs writeDB accountId
(addAccount acc accs) -
51Handling login's (1)
- handleLogin (Task (Maybe (Account Void)))
- handleLogin
- Txt "Type in your name and password...",
Br, Br - ?gtgt loginForm
- gtgt \login ? readAccountsDB
- gtgt \accounts ? return_V (hasAccount login
accounts) - loginForm (Task Login)
- loginForm editTask "Done" createDefault ltlt_at_
Submit -
-
52Handling login's (2)
- newLogin (Task (Account Void))
- newLogin newTask "newLogin" newLogin
-
- newLogin
- Br, Br, Txt "Type in name and password you
want to use...", Br ,Br - ?gtgt loginForm
- gtgt \login ? readAccountsDB
- gtgt \accounts ? case (invariantLogins ""
loginaccount.login \\ account lt- accounts)
of - (Just (_,error)) ? Txt error, Br, Br
- ?gtgt newLogin
- Nothing ? let newId length accounts
- newAccount login login
- , uniqueId newId
- , state Void
-
- in addAccountsDB newAccount accounts
- gtgt \_ ? Txt ("You are administrated
- , your id " lt newId)
- ?gtgt buttonTask "OK" (return_V
newAccount)
53Handling login's (3)
- loginProcedure (Task Int)
- loginProcedure newTask "loginProcedure"
loginProcedure -
- loginProcedure
- chooseTask ("Login", handleLogin)
- , ("New Login", newLogin
- gtgt \account -gt return_V (Just account))
-
- --
- buttonTask "Cancel" (return_V Nothing)
- gtgt \mbacc -gt case mbacc of
- Nothing ? Txt "Sorry, you have to try
again!",Br,Br - ?gtgt buttonTask "OK" loginProcedure
- (Just acc) ? return_V acc.uniqueId
54Defining a multi-user workflow system (1)
- Start world doHtmlServer (singleUserTask -1
True myAppl ) world - myAppl
- loginProcedure
- gtgt \myid ? readAccountsDB
- gtgt \accounts ? startNewTask myid True
- (assignTasks accounts ltlt_at_ TxtFile)
- assignTasks accounts
- andTasks ( acc.login.loginName ,
acc.uniqueId _at_ assignWork acc.login.loginName
acc.uniqueId - )
- \\ acc lt- accounts
-
- assignWork name i
55Defining a multi-user workflow system (2)
- assignWork Bool // traceOn
- (Task Void) // welcome task
- (acc ? Task acc) // administration task
- ((String,Int,acc) ? (Task a)) // \name
uniqueid admin -gt - ? (Task a) iData acc iData a
- Examples
-
- newsgroups
- marking
56Clean
- Introduction
- Defining Interactive Multi-user Workflow Systems
for the web - Defining a simple task an editor for a web form
- Combinators for constructing tasks
- Assigning tasks to users
- Logging in to a Multi-user Workflow System
- Implementation
- Basic idea of generic programming
- Generic functions for handling web forms i-Data
- Implementation of i-Tasks
- Conclusion Future Research
57Generic programming
- Some functions are more or less the same
- equality, unification, mapping, zipping, folding,
- pretty printers, parsers, generators,
- GAST automatic test system
- Graphical User Interfaces
- ???
- Define the general case once and for allby
induction on the structure of data types. - Automatically obtain a concrete function for any
concrete data type ! - Applicable for quite a large class of algorithms
- Exceptions make the rule !One can define
specialized instances for special types
58Example types
- List a Nil
- Cons a (List a)
- Rose a Rose a (List (Rose a))
- Tree a b Tip a
- Bin b (Tree a b) (Tree a b)
59Overloaded equality
- class infix 4 t t t ? Bool
- instance (List a) a
- where () Nil Nil True
- () (Cons x xs) (Cons y ys) x y xs
ys - () _ _ False
- instance (Rose a) a
- where () (Rose x xs) (Rose y ys) x y xs
ys - () _ _ False
- instance (Tree a b) a b
- where () (Tip x) (Tip y) x
y - () (Bin x ltx rtx) (Bin y lty rty) x y
ltx lty rtx rty - () _ _ False
60The idea of generic programming
Map_List
List a
List b
Map_Rose
Rose a
Rose b
61The idea of generic programming
Map_List
List a
List b
Map_Generic
Generic a
Generic b
Map_Rose
Rose a
Rose b
62The idea of generic programming
Map_List
List a
List b
fromList
toList
Map_Generic
Generic a
Generic b
toRose
fromRose
Map_Rose
Rose a
Rose b
63Generic programming
- We need a generic representation a way to
represent any value of any type - Clean is typed what is the type of such a
representation ? - One generic type which can represent all possible
types not possible type correctness of
programs becomes undecidable one would obtain a
complete different system - Solution use a couple of simple types to
represent any type !
64Generic type representation
- Example types
- List a Nil Cons a (List a)
- Rose a Rose a (List (Rose a))
- Tree a b Tip a Bin b (Tree a b) (Tree a
b) - Binary sums and products (in generic prelude)
- UNIT UNIT
- PAIR a b PAIR a b
- EITHER a b LEFT a RIGHT b
- Generic type representations
- ListG a EITHER UNIT (PAIR a (List a))
- RoseG a PAIR a (List (Rose a))
- TreeG a b EITHER a (PAIR b (PAIR (Tree a
b) (Tree a b)))
65Generic type representation
- Conversions to the generic domain can be
automatically generated - fromList (List a) ? ListG a
- fromList Nil LEFT UNIT
- fromList (Cons a as) RIGHT (PAIR a as)
- fromRose (Rose a) ? RoseG a
- fromRose (Rose a list_of_roses) PAIR a
list_of_roses - fromTree (Tree a b) ? TreeG a b
- fromTree (Tip a) LEFT a
- fromTree (Bin b leftTree rightTree) RIGHT (PAIR
b (PAIR leftTree rightTree))
66Generic type representation
- Conversions back to the user domain can be
automatically generated - toList (ListG a) ? List a
- toList LEFT UNIT Nil
- toList (RIGHT (PAIR a as)) Cons a as
- toRose (RoseG a) ? Rose a
- toRose (PAIR a list_of_roses) Rose a
list_of_roses - toTree (TreeG a b) ? Tree a b
- toTree (LEFT a) Tip a
- toTree (RIGHT (PAIR b (PAIR leftTree
rightTree))) Bin b leftTree rightTree
67Generic equality
- generic gEq a a a ? Bool
- gEq Int x y x y
- gEq Char x y x y
- gEq Bool x y x y
- gEq Real x y x y
- gEq String x y x y
- gEq UNIT UNIT UNIT True
- gEq PAIR eqx eqy (PAIR x1 y1) (PAIR x2 y2)
eqx x1 x2 eqy y1 y2 - gEq EITHER eqx eqy (LEFT x) (LEFT y) eqx x
y - gEq EITHER eqx eqy (RIGHT x) (RIGHT y) eqy
x y - gEq EITHER eqx eqy _ _ False
- gEq MyType
68Clean
- Introduction
- Defining Interactive Multi-user Workflow Systems
for the web - Defining a simple task an editor for a web form
- Combinators for constructing tasks
- Assigning tasks to users
- Logging in to a Multi-user Workflow System
- Implementation
- Basic idea of generic programming
- Generic functions for handling web forms i-Data
- Implementation of i-Tasks
- Conclusion Future Research
69editTask uses generic functions
- class iData a gForm , iCreateAndPrint,
iParse, iSpecialStore a - class iCreateAndPrint a iCreate, iPrint a
- class iCreate a gUpd a
- class iPrint a gPrint a
- class iParse a gParse a
- class iSpecialStore a gerda , TC a
- It requires the instantiation of several generic
functions for type "a" e.g. - gForm html form creation,
- gUpd form handling,
- gParse parsing,
- gPrint printing,
- gerda data storage I a relational database,
- TC Conversion to and from Dynamics, option used
to store functions -
- which can all, on request, automatically be
derived by the compiler !
70Implementation architecture
v T
71Implementation architecture
gForm Html code
v T
serialize gPrint store gerda
72Implementation architecture
73Implementation architecture
?v T?v
?v T?v
gUpd v T
v T
de-serialize gParse retrieve gerda
74Implementation architecture
?v T?v
gForm Html code
?v T?v
gUpd v T
v T
v T
serialize gPrint store gerda
de-serialize gParse retrieve gerda
75Generic functions used for i-Tasks / i-Data
- The following generic functions are used
- generic gForm a (Init, FormId a) HSt ? (Form
a, HSt) - can create an interactive Html form for any value
of any type - generic gUpd a UpdMode a ? (UpdMode, a)
- can update a value of any type given any change
made in a form - generic gPrint a a ? String
- can serialize a value of any (first-order) Clean
type - to store a form state in a page, file or database
- generic gParse a String ? Maybe a
- can de-serialize a value of any (first-order)
Clean type - to re-construct a form state
76Generating forms
- generic gForm a (Init, FormId a) HSt ?
(Form a, HSt) - FormId a
- id String // id uniquely identifying
the form - , initval a // initial value (Init) or new
value (Set) - , mode Mode // kind of form
- , lifespan Lifespan // where to store it,
and for how long - , storage StorageFormat // storage format
-
77Generating forms
- generic gForm a (Init, FormId a) HSt ?
(Form a, HSt) - FormId a
- id String // id uniquely identifying
the form - , initval a // initial value (Init) or new
value (Set) - , mode Mode // kind of form
- , lifespan Lifespan // where to store it,
and for how long - , storage StorageFormat // storage format
-
- Init Init Set
- Mode Edit Submit Display NoForm
- Lifespan Database TxtFile Session Page
Temp - StorageFormat StaticDynamic PlainString
78Generating forms
- generic gForm a (Init, FormId a) HSt ?
(Form a, HSt) - FormId a
- id String // id uniquely identifying
the form - , initval a // initial value (Init) or new
value (Set) - , mode Mode // kind of form
- , lifespan Lifespan // where to store it,
and for how long - , storage StorageFormat // storage format
-
- Init Init Set
- Mode Edit Submit Display NoForm
- Lifespan Database TxtFile Session Page
Temp - StorageFormat StaticDynamic PlainString
- HSt // State passed around single
threadedly
79Generating forms
- generic gForm a (Init, FormId a) HSt ?
(Form a, HSt) - FormId a
- id String // id uniquely identifying
the form - , initval a // initial value (Init) or new
value (Set) - , mode Mode // kind of form
- , lifespan Lifespan // where to store it,
and for how long - , storage StorageFormat // storage format
-
- Init Init Set
- Mode Edit Submit Display NoForm
- Lifespan Database TxtFile Session Page
Temp - StorageFormat StaticDynamic PlainString
- HSt // State passed around single
threadedly - Form a
- changed Bool // has the user edited the
form ? - , value a // current value in data domain
(feel)
80Updating a value (1)
- How can we reconstruct a value that has been
changed interactively ? - We only need to know 3 things
- Which type was it and what was its original
value? - Which parts have been changed in the original
value? -
- We don't need any knowledge about the html code !
- We only need to know which values have been
changed - We just need the position in its generic
representation - What are the changed values ?
- Simple case only a few basic cases
-
- Change existing value Int, Real, String, Bool,
- Create new values When you select a constructor
-
81Updating a value (2)
- generic gUpd a UpdMode a ? (UpdMode,a)
- UpdMode UpdSearch UpdValue Pos // search
for position - UpdCreate ConsPos // in generic
representation - UpdDone // copy the remaining expression
- UpdValue UpdI Int // new Integer value
- UpdR Real // new Real value
- UpdB Bool // new Boolean value
- UpdS String // new String value
- UpdC String // new Constructor value
- ConsPos ConsLeft
- ConsRight
- Pos Int
82Updating a value (3)
-
- gUpd Int (UpdSearch (UpdI ni) 0) _
(UpdDone,ni) - gUpd Int (UpdSearch val cnt) i
(UpdSearch val (cnt - 1), i) - gUpd Int (UpdCreate p) _ (UpdCreate
p, 0) - gUpd Int mode i (mode, i)
-
83Snapshot from Clean's CD shop
84Clean
- Introduction
- Defining Interactive Multi-user Workflow Systems
for the web - Defining a simple task an editor for a web form
- Combinators for constructing tasks
- Assigning tasks to users
- Logging in to a Multi-user Workflow System
- Implementation
- Basic idea of generic programming
- Generic functions for handling web forms i-Data
- Implementation of i-Tasks
- Conclusion Future Research
85What do we need for iTasks ?
- We need a notion of tasks inactive, active,
and completed - There is only one application for all users
- This application starts from scratch each time
information is communicated - The web has no notion of state, we have to store
all relevant information - We have to be able to find out what we were doing
-gt functions iData - We need to invent unique ids for a form and its
corresponding state - Careful tasks are dynamically created, can be
recursive ! - We have to find out which tasks are active and
deal with them - We have to support all options
- If active tasks are completed, we have to
activate the next set of tasks - We have to display the tasks in an understandable
way - We have to find out who has to do what, and show
relevant information only - We have to deal with multi-user aspects
- We have to gather trace information
- We have to remove unneeded administration of
completed tasks
86iTask Administration State
- TSt
- tasknr Int // unique form-id for
every task - , activated Bool // if assigned
activate, if returned completed - , userId Int // id of user who has to do
the task - , currentUserId Int // id of current
application user - , html HtmlTree // accumulator for html code
- , options Options // iData and iTasks
options - , hst HSt // iData state
- , trace Maybe Trace // for displaying task
trace -
87iTask Administration State
- TSt
- tasknr Int // unique form-id for
every task - , activated Bool // if assigned
activate, if returned completed - , userId Int // id of user who has to do
the task - , currentUserId Int // id of current
application user - , html HtmlTree // accumulator for html code
- , options Options // iData and iTasks
options - , hst HSt // iData state
- , trace Maybe Trace // for displaying task
trace -
- HtmlTree BT BodyTag // html code
- (_at__at_) infix 0 (Int,String) HtmlTree // code
with user id and task name - (-_at_) infix 0 Int HtmlTree // code not to
display to user id - (-) infixl 1 HtmlTree HtmlTree // place
code next to each other () infixl 1
HtmlTree HtmlTree // place code below each
other
88iTask Administration State
- TSt
- tasknr Int // unique form-id for
every task - , activated Bool // if assigned
activate, if returned completed - , userId Int // id of user who has to do
the task - , currentUserId Int // id of current
application user - , html HtmlTree // accumulator for html code
- , options Options // iData and iTasks
options - , hst HSt // iData state
- , trace Maybe Trace // for displaying task
trace -
- HtmlTree BT BodyTag // html code
- (_at__at_) infix 0 (Int,String) HtmlTree // code
with user id and task name - (-_at_) infix 0 Int HtmlTree // code not to
display to user id - (-) infixl 1 HtmlTree HtmlTree // place
code next to each other () infixl 1
HtmlTree HtmlTree // place code below each
other - Options
- tasklife Lifespan // default Session
- , taskstorage StorageFormat // default
PlainString - , taskmode Mode // default Edit
89Activating a task (simplified)
90Activating a task (simplified)
- Task a TSt ? (a,TSt)
- Each task is assumed to call doTask
- increment task number, such that this number is
unique - when activated call the task, create a default
value otherwise - when a task is finished, activate is returned
True, False otherwise.
91Activating a task (simplified)
- Task a TSt ? (a,TSt)
- Each task is assumed to call doTask
- increment task number, such that this number is
unique - when activated call the task, create a default
value otherwise - when a task is finished, activate is returned
True, False otherwise. - doTask String (Task a) ? (Task a)
iCreateAndPrint a - doTask taskname thistask mkTaskNoInc taskname
thistask o incTaskNr - where
- mkTaskNoInc taskname thistask tstactivated,
tasknr, options - not activated (createDefault, tst)
- (val,tst) thistask tst
- (val, tst tasknr tasknr, options
options) - incTaskNr tst tst tasknr incNr
tst.tasknr - where incNr 0
- incNr iis i1is
92The bind is now easy... a standard bind can be
used
- (gtgt) infix 1 (Task a) (a ? Task b) ? Task b
- (gtgt) taska taskb bind
- where
- bind tst
- (a, tst) taska tst
- taskb a tst
- (gtgt) infix 1 (Task a) (Task b) ? Task b
- (gtgt) taska taskb bind
- where
- bind tst
- (_, tst) taska tst
- taskb tst
93A simple combinator ?gtgt
- (?gtgt) infix 5 BodyTag (Task a) -gt (Task a)
iCreate a - (?gtgt) prompt thistask myTask
- where
- myTask tsthtml, activated
- not activated (createDefault, tst)
- (a, tstactivated, html nhtml)
thistask tst html BT - activated (a, tst html html)
- (a, tst html html BT prompt
nhtml)
94A simple combinator --
- (--) infixr 4 (Task a) (Task b) ? (Task
(a,b)) iCreateAndPrint a iCreateAndPrint b - (--) taska taskb mkTask "--" (doAndTask
(taska, taskb)) - doAndTask (taska, taskb) tsttasknr, html
- (a, tstactivated adone, html ahtml)
- mkParSubTask "andTask" 0 taska tst html
BT - (b, tstactivated bdone, html bhtml)
- mkParSubTask "andTask" 1 taskb tst tasknr
tasknr, html BT - ((a,b), tst activated adone bdone, html
html ahtml bhtml)
95A simple combinator --
- (--) infixr 4 (Task a) (Task b) ? (Task
(a,b)) iCreateAndPrint a iCreateAndPrint b - (--) taska taskb mkTask "--" (doAndTask
(taska, taskb)) - doAndTask (taska, taskb) tsttasknr, html
- (a, tstactivated adone, html ahtml)
- mkParSubTask "andTask" 0 taska tst html
BT - (b, tstactivated bdone, html bhtml)
- mkParSubTask "andTask" 1 taskb tst tasknr
tasknr, html BT - ((a,b), tst activated adone bdone, html
html ahtml bhtml) - mkParSubTask name i task tst task (newSubTaskNr
(setActivated (subTaskNr i tst))) - subTaskNr i tst tst tasknr i
tst.tasknr - newSubTaskNr tst tst tasknr -1
tst.tasknr
96Clean
- Introduction
- Defining Interactive Multi-user Workflow Systems
for the web - Defining a simple task an editor for a web form
- Combinators for constructing tasks
- Assigning tasks to users
- Logging in to a Multi-user Workflow System
- Implementation
- Basic idea of generic programming
- Generic functions for handling web forms i-Data
- Implementation of i-Tasks
- Conclusion Future Research
97Conclusions
- Compact specification, many details are handled
automatically - very intuitive
- All "standard" workflows patterns offered
- but we are lacking a graphical editor...
- Offers a lot of additional expressive power
- Typed
- Workflows are dynamically generated
- Additional Workflow Patterns lazy send /
receive, -!gt - Higher Order Workflows
- Highly re-usable code
- First industrial real-world application has been
made (Car Damage Negotiation System, ABZ)
98Future Work
- Show applicability via more, large real world
applications - Combine with Client site evaluation
- Fast Clean interpreter (Jan-Martin Jansen)
running in browser - add Ajax technology
- Integrate with main stream web development tools
(Dreamweaver) - Improve performance
- Practical issues What is the ideal set of
combinators ? - Can we exploit lazy evaluation ?
- Theoretical issues What is the minimal set of
combinators ? - How does it compare with other approaches Petri
Nets, Process Algebra, µCRL ? - Can we prove properties of a workflow system ?
- What kind of static properties can we analyse ?