I tasks i nteractive workflow tasks for the wwweb
Download
1 / 98

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


  • 355 Views
  • Updated 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

Related searches for i-Tasks - i nteractive workflow Tasks for the WWWEB \_\_\_\_\_\_\_\_\_\_\_

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 l.jpg

i-Tasks-interactive workflow Tasksfor the WWWEB___________

Rinus Plasmeijer

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


Clean l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
A very small *complete* example III

  • simple:: (Task [Int])

  • simple = editTask "Done" createDefault


A very small complete example iv l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
A very small *complete* example IV

  • simple:: (Task Person)

  • simple = editTask "Done" createDefault


A very small complete example iv submit l.jpg
A very small *complete* example IV Submit

  • simple:: (Task Person)

  • simple = editTask "Done" createDefault <<@ Submit


A very small complete example iv submit database l.jpg
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 l.jpg
A very small *complete* example IV, Submit, TxtFile

  • simple:: (Task Person)

  • simple = editTask "Done" createDefault <<@ Submit <<@ TxtFile


Clean23 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
Sequence of iTasks

  • sumInt:: (Task Int)

  • sumInt

  • = editTask "Done" createDefault

  • =>> \v1editTask "Done" createDefault

  • =>> \v2 [Txt "+", Hr [] ]

  • !>>return_D (v1 + v2)


Simple coffeemachine 1 3 l.jpg
Simple Coffeemachine (1/3)


Simple coffeemachine 2 3 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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[email protected]::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 l.jpg
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 l.jpg
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 l.jpg
Delegate a Task

  • delegateToSomeone:: Int (Task a) [Int]  (Task a)| iData a

  • delegateToSomeoneme task set = newTask "delegateToSomeone" doDelegate

  • where

  • doDelegate

  • = orTasks [ ("Waiting for " <+++ who

  • , [email protected]::chooseTask [("I Will Do It“, return_V who)]

  • ) \\ who set

  • ]

  • =>> \volunteer[email protected]::stopIt-!> task

  • =>> \(stopped, TClosure task) 

  • if (isJust stopped) (delegateToSomeonemetask set) task

  • stopIt= stop-||- ([email protected]::stop)

  • stop= chooseTask [("Stop“, return_V True)]


Clean45 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
The idea of generic programming

Map_List

List a

List b

Map_Rose

Rose a

Rose b


The idea of generic programming61 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
Implementation architecture

Clean Application

v :: T


Implementation architecture71 l.jpg
Implementation architecture

Browser

Html code

Web Server

File / Data Base

Clean Application

gForm: Html code

v :: T

serialize: gPrint

store: gerda


Implementation architecture72 l.jpg
Implementation architecture

Browser

Web Server

File / Data Base


Implementation architecture73 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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

  • | ([email protected]:) 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 l.jpg
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

  • | ([email protected]:) 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 l.jpg
Activating a task (simplified)

  • :: Task a :== *TSt *(a,*TSt)


Activating a task simplified90 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 l.jpg
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 ?


ad