i tasks i nteractive workflow tasks for the wwweb l.
Download
Skip this Video
Loading SlideShow in 5 Seconds..
i-Tasks - i nteractive workflow Tasks for the WWWEB \_\_\_\_\_\_\_\_\_\_\_ PowerPoint Presentation
Download Presentation
i-Tasks - i nteractive workflow Tasks for the WWWEB \_\_\_\_\_\_\_\_\_\_\_

Loading in 2 Seconds...

play fullscreen
1 / 98

i-Tasks - i nteractive workflow Tasks for the WWWEB \_\_\_\_\_\_\_\_\_\_\_ - PowerPoint PPT Presentation


  • 376 Views
  • Uploaded on

i-Tasks - i nteractive workflow Tasks for the WWWEB ___________ Rinus Plasmeijer University of Nijmegen www.cs.ru.nl/~clean Clean Introduction Defining Interactive Multi-user Workflow Systems for the web Defining a simple task: an editor for a web form Combinators for constructing tasks

loader
I am the owner, or an agent authorized to act on behalf of the owner, of the copyrighted work described.
capcha
Download Presentation

PowerPoint Slideshow about 'i-Tasks - i nteractive workflow Tasks for the WWWEB \_\_\_\_\_\_\_\_\_\_\_' - bernad


An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -
Presentation Transcript
i tasks i nteractive workflow tasks for the wwweb

i-Tasks-interactive workflow Tasksfor the WWWEB___________

Rinus Plasmeijer

University of Nijmegen www.cs.ru.nl/~clean

clean
Clean
  • 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
clean3
Clean
  • 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
clean4
Clean
  • 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 <-> Monads
      • Re-usage: Generic programming included <-> Generic Haskell preprocessor
      • Hybrid typing: Static as well as Dynamic typing <-> 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 -> Clean compilers
      • Haskell / Clean code can be combined in next Clean release
why workflows
Why 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
i tasks approach i
i -Tasks Approach I
  • Study “Workflow Patterns” (Van der Aalst, ter Hofstede, Kiepuszewski, Barros)
    • > 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
i tasks approach ii
i -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
  • < 1000 lines of code based on Clean’s i-Data library for the web
i tasks approach iii
i -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 <--> 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
clean9
Clean
  • 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
a very small complete example i
A 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
testing an i tasks application
Testing an i –Tasks application

Browser

Http 1.0 Web Server

i –Tasks Application

Changes in Forms

Htmlcode

Clean Application

final setting of an i tasks application
Final setting of an i –Tasks application

Browser

Http 1.1 Web Server

i –Tasks Application 2

i –Tasks Application n

i –Tasks Application 1

Changes in Forms

Htmlcode

a very small complete example ii
A 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
a very small complete example iii
A very small *complete* example III
  • simple:: (Task [Int])
  • simple = editTask "Done" createDefault
a very small complete example iv
A 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
edittask
editTask
  • 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.
edittask uses generic functions
editTask uses generic functions
  • class iData a | gForm {|*|} , iCreateAndPrint, iParse, iSpecialStorea
  • class iCreateAndPrint a | iCreate, iPrinta
  • class iCreate a| gUpd {|*|} a
  • class iPrint a| gPrint {|*|} a
  • class iParse a| gParse {|*|} a
  • class iSpecialStorea| gerda {|*|}, TCa
  • 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 !
options
Options
  • A task or combination of tasks, can have several options:
  • class (<<@) infixl 3 b :: (Task a) b  Task a
  • instance<<@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
a very small complete example iv19
A very small *complete* example IV
  • simple:: (Task Person)
  • simple = editTask "Done" createDefault
a very small complete example iv submit
A very small *complete* example IV Submit
  • simple:: (Task Person)
  • simple = editTask "Done" createDefault <<@ Submit
a very small complete example iv submit database
A very small *complete* example IV, Submit, Database
  • simple:: (Task Person)
  • simple = editTask "Done" createDefault <<@ Submit <<@ Database
a very small complete example iv submit txtfile
A very small *complete* example IV, Submit, TxtFile
  • simple:: (Task Person)
  • simple = editTask "Done" createDefault <<@ Submit <<@ TxtFile
clean23
Clean
  • 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
sequencing of tasks
Sequencing of tasks
  • Sequencing / composition of tasks (monadic style):
  • (=>>) infix 1 :: (Task a) (a  Task b)  Task b
  • (#>>) infixl 1 :: (Task a) (Task b)  Task b
  • Returning plain values as a Task value
  • return_V :: a  Task a | iData a
prompting
Prompting
  • 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:
  • (?>>) infix 5 :: [BodyTag] (Task a)  Task a | iData a
  • (!>>) infix 5 :: [BodyTag] (Task a)  Task a | iData a
html code
Html 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 <a></a>
  • | Abbr [Std_Attr] String // abbreviation <abbr></abbr>
  • | Acronym [Std_Attr] String // acronym <acronym></acronym>
  • | Address [Std_Attr] String // address <address></address>
  • | Applet [Applet_Attr] String // applet <applet></applet>
  • | Area [Area_Attr] // link area in an image <area>
  • | B [Std_Attr] String // bold <b></b>
  • | Txt String // plain text
  • | U [Std_Attr] String // underlined text <u></u>
  • | Ul [Ul_Attr] [BodyTag] // unordered list <ul></ul>
  • | Var [Std_Attr] String // variable text <var></var>
sequence of itasks
Sequence of iTasks
  • sumInt:: (Task Int)
  • sumInt
  • = editTask "Done" createDefault
  • =>> \v1editTask "Done" createDefault
  • =>> \v2 [Txt "+", Hr [] ]
  • !>>return_D (v1 + v2)
simple coffeemachine 2 3
Simple Coffeemachine (2/3)
  • simpleCoffee= foreverTask SimlpeCoffeeMachine
  • SimlpeCoffeeMachine:: (Task String)
  • SimlpeCoffeeMachine
  • = [Txt "Choose product:",Br,Br]
  • ?>>chooseTask
  • [ ("Coffee", return_V ("Coffee"))
  • , ("Tea", return_V ("Tea"))
  • ]
  • =>> \product [Txt ("Enjoy your " <+++ product)]
  • ?>>chooseTask
  • [ "OK“, return_Vproduct]
simple coffeemachine 3 3
Simple Coffeemachine (3/3)
  • simpleCoffee= foreverTask SimlpeCoffeeMachine
  • SimlpeCoffeeMachine:: (Task String)
  • SimlpeCoffeeMachine
  • = [Txt "Choose product:",Br,Br]
  • ?>>chooseTask
  • [ ("Coffee", return_V ("Coffee"))
  • , ("Tea", return_V ("Tea"))
  • ]
  • =>> \product [Txt ("Enjoy your " <+++ product)]
  • ?>>buttonTask "OK" (return_Vproduct)
all kinds of task combinators
All 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
coffeemachine 2 3
Coffeemachine (2/3)
  • infCoffee= foreverTask CoffeeMachine
  • CoffeeMachine:: Task (String, Int)
  • CoffeeMachine
  • = [Txt "Choose product:", Br, Br]
  • ?>>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"))
  • ]
  • =>> \(toPay, product) [Txt ("Chosen product: " <+++ product), Br, Br]
  • ?>>getCoins (toPay, 0)
  • =>> \(cancel, returnMoney)
  • let nproduct =if cancel "Cancelled" product in
  • [Txt ("product = " <+++ nproduct <+++ ",
  • returned money = " <+++ returnMoney), Br, Br]
  • ?>>buttonTask"Thanks" (return_V (nproduct, returnMoney))
coffeemachine 3 3
Coffeemachine (3/3)
  • getCoins:: (Int, Int) -> Task (Bool, Int)
  • getCoins (toPay, paid) = newTask "getCoins" getCoins`
  • where
  • getCoins`
  • = [Txt ("To pay: " <+++ toPay), Br, Br]
  • ?>>chooseTask [ (c +++> " cts", return_V (False, c)) \\ c coins ]
  • -||-
  • buttonTask"Cancel" (return_V (True, 0))
  • =>> handleMoney
  • handleMoney (cancel, coin)
  • | cancel = return_V (True, paid)
  • | toPay - coin > 0 = getCoins (toPay - coin, paid + coin)
  • | otherwise = return_V (False, coin - toPay)
  • coins = [ 5, 10, 20, 50, 100, 200 ]
clean35
Clean
  • 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
multi user combinators
Multi-user combinators
  • Multi-user :
  • (@:) infix 3 :: (String, Int) (Task a)  (Task a)| iData a
  • (@::) infix 3 :: Int (Task a)  (Task a)| iData a
review task 1 3
Review Task (1/3)
  • :: Review =Approved|Cancelled|NeedsRework TextArea |Draft
  • reviewTask:: a  (Task Review) | iData a
  • reviewTask v
  • = [toHtml v, Br, Br]
  • ?>>chooseTask
  • [ ("Rework", editTask "Done" (NeedsRework createDefault) <<@ Submit)
  • , ("Approved", return_VApproved)
  • , ("Reject", return_VRejected)
  • ]
review task 2 3
Review Task (2/3)
  • taskToReview:: Int (a, a Task a) Task (a, Review) | iData a
  • taskToReviewreviewer (val, task)
  • = newTask "taskToReview" taskToReview`
  • where
  • taskToReview`
  • = task val
  • =>> \newvalreviewer@::reviewTask newval
  • =>> \review [Txt ("Reviewer " <+++ reviewer <+++ " says ") , toHtml review, Br]
  • ?>>editTask "OK" Void
  • #>>casereviewof
  • (NeedsRework _) taskToReviewreviewer (newval, task)
  • else  return_V (newval, review)
review task 3 3
Review Task (3/3)
  • :: QForm = { toComp :: String
  • , startDate :: HtmlDate
  • , endDate :: HtmlDate
  • , estimatedHours :: Int
  • , description :: TextArea
  • , price :: Real
  • }
  • startTask:: Task (QForm, Review)
  • startTask = taskToReview1 (createDefault, mytask)
  • mytask:: a  (Task a) | iData a
  • mytask v = [Txt "Fill in Form:", Br, Br]
  • ?>>editTask "TaskDone" v <<@ Submit
higher order tasks
Higher-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
  • (-!>) infix 4 :: (Task stop) (Task a)  (Task (Maybe stop, TClosure a)) | iData stop & iData a
delegate a task
Delegate a Task
  • delegateToSomeone:: Int (Task a) [Int]  (Task a)| iData a
  • delegateToSomeoneme task set = newTask "delegateToSomeone" doDelegate
  • where
  • doDelegate
  • = orTasks [ ("Waiting for " <+++ who
  • , who@::chooseTask [("I Will Do It“, return_V who)]
  • ) \\ who set
  • ]
  • =>> \volunteervolunteer@::stopIt-!> task
  • =>> \(stopped, TClosure task) 
  • if (isJust stopped) (delegateToSomeonemetask set) task
  • stopIt= stop-||- (me@::stop)
  • stop= chooseTask [("Stop“, return_V True)]
clean45
Clean
  • 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
login handling types and functions
Login 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)
itasks can be used for persistent storage of information
iTasks 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
creating a database for a login accounts
Creating 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
  • addAccountsDBacc accs = writeDB accountId (addAccount acc accs)
creating a database for a login accounts49
Creating 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
  • addAccountsDBacc accs = writeDB accountId (addAccount acc accs)
creating a database for a login accounts50
Creating 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))
  • addAccountsDBacc accs = writeDB accountId (addAccount acc accs)
handling login s 1
Handling login's (1)
  • handleLogin:: (Task (Maybe (Account Void)))
  • handleLogin
  • = [Txt "Type in your name and password...", Br, Br]
  • ?>>loginForm
  • =>> \loginreadAccountsDB
  • =>> \accountsreturn_V (hasAccountloginaccounts)
  • loginForm:: (Task Login)
  • loginForm = editTask "Done" createDefault <<@ Submit
handling login s 2
Handling 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]
  • ?>> loginForm
  • =>> \loginreadAccountsDB
  • =>> \accounts case (invariantLogins "" [login:[account.login \\ account <- accounts]]) of
  • (Just (_,error))  [Txt error, Br, Br]
  • ?>>newLogin
  • Nothinglet newId = length accounts
  • newAccount = { login = login
  • , uniqueId = newId
  • , state = Void
  • }
  • inaddAccountsDB newAccount accounts
  • =>> \_  [Txt ("You are administrated
  • , your id = " <+++ newId)]
  • ?>>buttonTask "OK" (return_V newAccount)
handling login s 3
Handling login's (3)
  • loginProcedure:: (Task Int)
  • loginProcedure = newTask "loginProcedure" loginProcedure`
  • loginProcedure`
  • = chooseTask [ ("Login", handleLogin)
  • , ("New Login", newLogin
  • =>> \account -> return_V (Justaccount))
  • ]
  • -||-
  • buttonTask "Cancel" (return_VNothing)
  • =>> \mbacc -> casembaccof
  • Nothing [Txt "Sorry, you have to try again!",Br,Br]
  • ?>> buttonTask "OK" loginProcedure
  • (Just acc) return_V acc.uniqueId
defining a multi user workflow system 1
Defining a multi-user workflow system (1)
  • Start world = doHtmlServer (singleUserTask-1 True myAppl ) world
  • myAppl
  • = loginProcedure
  • =>> \myidreadAccountsDB
  • =>> \accountsstartNewTaskmyid True
  • (assignTasksaccounts<<@ TxtFile)
  • assignTasks accounts
  • = andTasks [ ( acc.login.loginName , acc.uniqueId @:: assignWork acc.login.loginName acc.uniqueId
  • )
  • \\ acc <- accounts
  • ]
  • assignWork name i = …
defining a multi user workflow system 2
Defining 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 ->
  •  (Task [a])| iData acc & iData a
  • Examples:
  • newsgroups
  • marking
clean56
Clean
  • 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
generic programming
Generic 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 caseonce 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…

example types
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)
overloaded equality
Overloaded 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 ltxrtx) (Bin y ltyrty)= x == y && ltx==lty && rtx==rty
  • (==) _ _ = False
the idea of generic programming
The idea of generic programming

Map_List

List a

List b

Map_Rose

Rose a

Rose b

the idea of generic programming61
The idea of generic programming

Map_List

List a

List b

Map_Generic

Generic a

Generic b

Map_Rose

Rose a

Rose b

the idea of generic programming62
The idea of generic programming

Map_List

List a

List b

fromList

toList

Map_Generic

Generic a

Generic b

fromRose

toRose

Map_Rose

Rose a

Rose b

generic programming63
Generic 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 !

generic type representation
Generic 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)))
generic type representation65
Generic type representation

Conversions to the generic domain can be automatically generated

  • fromList:: (List a) ListG a
  • fromListNil = LEFTUNIT
  • 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))
generic type representation66
Generic type representation
  • Conversions back to the user domain can be automatically generated
  • toList:: (ListG a) List a
  • toListLEFTUNIT = 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
generic equality
Generic equality
  • generic gEqa :: 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|} … =
clean68
Clean
  • 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
edittask uses generic functions69
editTask uses generic functions
  • class iData a | gForm {|*|} , iCreateAndPrint, iParse, iSpecialStorea
  • class iCreateAndPrint a | iCreate, iPrinta
  • class iCreate a| gUpd {|*|} a
  • class iPrint a| gPrint {|*|} a
  • class iParse a| gParse {|*|} a
  • class iSpecialStorea| gerda {|*|}, TCa
  • 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 !
implementation architecture
Implementation architecture

Clean Application

v :: T

implementation architecture71
Implementation architecture

Browser

Html code

Web Server

File / Data Base

Clean Application

gForm: Html code

v :: T

serialize: gPrint

store: gerda

implementation architecture72
Implementation architecture

Browser

Web Server

File / Data Base

implementation architecture73
Implementation architecture

Browser

Web Server

File / Data Base

Clean Application

∆v :: T∆v

∆v :: T∆v

gUpd: v` :: T

v :: T

de-serialize: gParse

retrieve: gerda

implementation architecture74
Implementation architecture

Browser

Html code

Web Server

File / Data Base

Clean Application

∆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

generic functions used for i tasks i data
Generic functions used for i-Tasks / i-Data
  • The following generic functions are used:
  • genericgForma:: (Init,FormIda) *HSt *(Form a, *HSt)
  • can create an interactive Html form for any value of any type
  • genericgUpda:: UpdMode a (UpdMode, a)
  • can update a value of any type given any change made in a form
  • genericgPrint a:: a String
  • can serialize a value of any (first-order) Clean type
  • to store a form state in a page, file or database
  • genericgParsea:: String  Maybe a
  • can de-serialize a value of any (first-order) Clean type
  • to re-construct a form state
generating forms
Generating forms
  • genericgForma:: (Init, FormIda) *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
  • }
generating forms77
Generating forms
  • genericgForma:: (Init, FormIda) *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
generating forms78
Generating forms
  • genericgForma:: (Init, FormIda) *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
generating forms79
Generating forms
  • genericgForma:: (Init, FormIda) *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)
  • , form:: [BodyTag] // html code representing view domain (look)
  • }
updating a value 1
Updating 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
        • Complication : change of form may depend on the change of others
updating a value 2
Updating a value (2)
  • generic gUpda :: 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
updating a value 3
Updating 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)
clean84
Clean
  • 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
what do we need for itasks
What 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 -> functions + iData
    • We need to invent unique id’s 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
i t ask administration st ate
iTask 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
  • }
i t ask administration st ate87
iTask 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
  • | (@@:) infix 0 (Int,String)HtmlTree // code with user id and task name
  • | (-@:) 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
i t ask administration st ate88
iTask 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
  • | (@@:) infix 0 (Int,String)HtmlTree // code with user id and task name
  • | (-@:) 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
  • , gc:: GarbageCollect // default: Collect
  • }
activating a task simplified
Activating a task (simplified)
  • :: Task a :== *TSt *(a,*TSt)
activating a task simplified90
Activating 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.
activating a task simplified91
Activating 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 tst=:{activated, tasknr, options}
  • | notactivated = (createDefault, tst)
  • # (val,tst) = thistask tst
  • = (val, {tst & tasknr = tasknr, options = options})
  • incTaskNr tst = {tst & tasknr = incNr tst.tasknr}
  • where incNr [] = [0]
  • incNr [i:is] = [i+1:is]
the bind is now easy a standard bind can be used
The bind is now easy... a standard bind can be used
  • (=>>) infix 1 :: (Task a) (a  Task b)  Task b
  • (=>>) taskataskb = bind
  • where
  • bind tst
  • # (a, tst) = taska tst
  • = taskb a tst
  • (#>>) infix 1 :: (Task a) (Task b)  Task b
  • (#>>) taskataskb = bind
  • where
  • bind tst
  • # (_, tst) = taska tst
  • = taskb tst
a simple combinator
A simple combinator: ?>>
  • (?>>) infix 5 :: [BodyTag] (Task a) -> (Task a) | iCreate a
  • (?>>) prompt thistask = myTask
  • where
  • myTask tst=:{html, activated}
  • | notactivated = (createDefault, tst)
  • # (a, tst=:{activated, html = nhtml}) = thistask {tst & html = BT []}
  • | activated = (a, {tst & html = html})
  • = (a, {tst & html = html +|+ BT prompt +|+ nhtml})
a simple combinator94
A simple combinator: -&&-
  • (-&&-) infixr 4 :: (Task a) (Task b)  (Task (a,b)) | iCreateAndPrint a & iCreateAndPrint b
  • (-&&-) taskataskb = mkTask "-&&-" (doAndTask (taska, taskb))
  • doAndTask (taska, taskb) tst=:{tasknr, html}
  • # (a, tst=:{activated = adone, html = ahtml})
  • = mkParSubTask "andTask" 0 taska {tst & html = BT []}
  • # (b, tst=:{activated = bdone, html = bhtml})
  • = mkParSubTask "andTask" 1 taskb {tst & tasknr = tasknr, html = BT []}
  • = ((a,b), {tst & activated = adone&&bdone, html = html +|+ ahtml +|+ bhtml})
a simple combinator95
A simple combinator: -&&-
  • (-&&-) infixr 4 :: (Task a) (Task b)  (Task (a,b)) | iCreateAndPrint a & iCreateAndPrint b
  • (-&&-) taskataskb = mkTask "-&&-" (doAndTask (taska, taskb))
  • doAndTask (taska, taskb) tst=:{tasknr, html}
  • # (a, tst=:{activated = adone, html = ahtml})
  • = mkParSubTask "andTask" 0 taska {tst & html = BT []}
  • # (b, tst=:{activated = 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] }
  • setActivated tst = { tst & activated = True }
clean96
Clean
  • 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
conclusions
Conclusions
  • 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, -!>
    • Higher Order Workflows
    • Highly re-usable code
  • First industrial real-world application has been made (Car Damage Negotiation System, ABZ)
future work
Future 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 ?