Encapsulated State
description
Transcript of Encapsulated State
Seif Haridi and Peter Van Roy 1
Encapsulated State
Seif Haridi
Peter Van Roy
Seif Haridi and Peter Van Roy 2
Encapsulated State
State as a group of memory cells
• The box O can remember information between independent invocations, it has a memory
• The basic elements of explicit state
• Index datatypes
• Basic techniques and ideas of using state in program design
Group of functions and procedures that operateon the state
An Interface that hidesthe state
The box O
Seif Haridi and Peter Van Roy 3
Encapsulated State II
State as a group of memory cells
• What is the difference between implicit state and explicit state
• What is the difference between state in general and encapsulate state
• Component based programming and object-oriented programming
• Abstract data types using encapsulated state
Group of functions and procedures that operateon the state
An Interface that hidesthe state
The box O
Seif Haridi and Peter Van Roy 4
What is state?
• State is a sequence of values that evolves in time that contains the intermediate results of a desired computation
• Declarative programs can also have state according this definition
• Consider the following program
fun {Sum Xs A} case Xs of X|Xr then {Sum Xr A+X} [] nil then A end end
{Show {Sum [1 2 3 4] 0}}
Seif Haridi and Peter Van Roy 5
What is implicit state?
The two arguments Xs and A
represents an implicit state
Xs A
[1 2 3 4] 0
[2 3 4] 1
[3 4] 3
[4] 6
nil 10
fun {Sum Xs A} case Xs of X|Xr then {Sum Xr A+X} [] nil then A end end
{Show {Sum [1 2 3 4] 0}}
Seif Haridi and Peter Van Roy 6
What is explicit state: Example?
Xan unboundvariable
XA cell C is created with initial value 5X is bound to C
5
XThe cell C, X is bound to, is assigned the value 6
6
C
C
Seif Haridi and Peter Van Roy 7
What is explicit state: Example?
Xan unboundvariable
XA cell C is created with initialvalue 5X is bound to C
5
XThe cell C, X is bound to, is assigned the value 6
6
C
C
• The cell is a value container with a unique identity• X is really bound to the identity of the cell• When the cell is assigned, X do notchange
Seif Haridi and Peter Van Roy 8
What is explicit state?• X = {NewCell I}
– Creates a cell with initial value I
– Binds X to the identity of the cell
• Example: X = {NewCell 0}
• {Assign +X J}
– Assumes X is bound to a cell C (otherwise exception)
– Changes the content of C to become J
• Y = {Access +X}
– Assumes X is bound to a cell C (otherwise exception)
– Binds Y to the value contained in C
Seif Haridi and Peter Van Roy 9
Examples• X = {NewCell 0}
• {Assign X 5}
• Y = X
• {Assign Y 10}
• {Access X} == 10 % returns true
• X == Y % returns true
X 0
X 5
Y
X 10
Y
Seif Haridi and Peter Van Roy 10
Examples• X = {NewCell 10}
Y = {NewCell 10}
• X == Y % returns false
• Because X and Y refer to different cells, with different identities
• {Access X} == {Access Y}returns true
X 10
Y 10
Seif Haridi and Peter Van Roy 11
Examples
• X = {NewCell 0}
• {Assign X 5}
• Y = X
• {Assign Y 10}
• X == 10returns true
X 0
X 5
Y
X 10
Y
Seif Haridi and Peter Van Roy 12
The model extented with cells
Semantic stack(Thread 1)
Semantic stack(Thread n)
w = f(x)z = person(a:y)y = 1u = 2x
1: w2: x........
.....
single assignmentstore
mutable store
Seif Haridi and Peter Van Roy 13
The stateful model
s::= skip empty statement| s1 s2 statement sequence
| ... | thread s1 end thread creation| {NewCell x c} cell creation| {Exchange c x y} cell exchange
Unify (bind) x to the old value of c and set the contentof the cell c to y
Seif Haridi and Peter Van Roy 14
The stateful model
| {NewCell x c} cell creation| {Exchange c x y} cell exchange
Unify (bind) x to the old value of c and set the contentof the cell c to y
proc {Assign C X} {Exchange C _ X} end
fun {Access C} X in{Exchange C X X}X end
Seif Haridi and Peter Van Roy 15
Do we need explicit state?
• Up to now the computation model we introduced in the previous lectures did not have any notion of explicit state
• And important question is: do we need explicit state?
• There is a number of reasons for introducing state, we discuss them some of them here
Seif Haridi and Peter Van Roy 16
Modular programs
• A system (program) is modular if changes (updates) in the program are confined to the components where the functionality are changed
• Here is an example where introduction of explicit state in a well confined way leads to program modularity compared to programs that are written using only the declarative model (where evey component is a function)
Seif Haridi and Peter Van Roy 17
Encapsulated state I
• Assume we have three persons, P, U1 and U2
• P is a programmer that developed a component M that provides two functions F and G
• U1 and U2 are system builders that use the component M
fun {MF}fun {F ...} Definition of Fendfun {G ...} Definition of Gend
in ’export’(f:F g:G)endM = {MF}
Seif Haridi and Peter Van Roy 18
Encapsulated state I
• Assume we have three persons, P, U1 and U2
• P is a programmer that developed a component M the provides two functions F and G
• U1 and U2 are system builders that use the component M
functor MFexport f:F g:Gdefine fun {F ...} Definition of F end fun {G ...} Definition of G endend
Seif Haridi and Peter Van Roy 19
Encapsulated state II
• User U2 has a demanding application
• He wants to extend the module M to enable him to monitor how many times the function F is invoked in his application
• He goes to P, and asks him to do so without changing the interface to M
fun {M}
fun {F ...} Definition of Fendfun {G ...} Definition of Gend
in ’export’(f:F g:G)
end
Seif Haridi and Peter Van Roy 20
Encapsulated state III
• This cannot be done in the declarative model because F cannot remember its previous invocations
• The only way to do it there is to change the interface to F by adding two extra arguments FIn and FOut
fun {F ... +FIn ?FOut} FOut = FIn+1 ... end
• The rest of the program always remembers the previous number of invocations (FIn), and FOut retruns the new number of invocation
• But this changes the interface!
Seif Haridi and Peter Van Roy 21
fun {MF}X = {NewCell 0}
fun {F ...} {Assign X {Access X}
+1}
Definition of Fendfun {G ...} Definition of G endfun {Count} {Access X} end
in ’export’(f:F g:G c:Count)endM = {MF}
Encapsulated state III
• A cell is created when MF is called
• Due to lexical scoping the cell is only visible to the created version of F and Count
• The M.f did not change• New function M.c is
available• X is hidden only visible
inside M (encapsulated state)
Seif Haridi and Peter Van Roy 22
Relationship between the declarative model and the stateful model
• Declarative programming guarantees by construction that each procedure computes a function
• This means each component (and subcomponent) is a function
• It is possible to use encapsulated state (cells) so that a component is declarative from outside, and stateful from the inside
• Considered as a black-box the program procedure is still a function
Seif Haridi and Peter Van Roy 23
Programs with accumulators
localfun {Sum1 Xs A}
case Xs of X|Xr then {Sum1 Xr A+X} [] nil then A end
endin fun {Sum Xs} {Sum1 Xs 0} end
Seif Haridi and Peter Van Roy 24
Programs with accumulators
fun {Sum Xs}fun {Sum1 Xs A}
case Xs of X|Xr then {Sum1 Xr A+X} [] nil then A end
endin {Sum1 Xs 0} end
fun {Sum Xs}fun {Sum1 Xs}
case Xs of X|Xr then
{Assign A X+{Access A}}
{Sum1 Xr} [] nil then {Access A} end
end A = {NewCell 0}
in {Sum1 Xs} end
Seif Haridi and Peter Van Roy 25
Programs with accumulators
fun {Sum Xs}fun {Sum1 Xs}
case Xs of X|Xr then
{Assign A X+{Access A}}
{Sum1 Xr} [] nil then {Access A} end
end A = {NewCell 0}
in {Sum1 Xs} end
fun {Sum Xs} A = {NewCell 0}
in{ForAll Xs proc {$ X}
{Assign A X+{Access A}} end}{Access A}
end
Seif Haridi and Peter Van Roy 26
Programs with accumulators
fun {Sum Xs} A = {NewCell 0}
in{ForAll Xs proc {$ X}
{Assign A X+{Access A}} end}{Access A}
end
fun {Sum Xs} A = {NewCell 0}
infor X in Xs do {Assign A X+{Access A}} end{Access A}
endThe state is encapsulated inside each procedure invocation
Seif Haridi and Peter Van Roy 27
Indexed Collections
• Indexed collections groups a set of (partial) values
• The individual elements are accessible through an index
• The declarative model provides:
– tuples, e.g. date(17 december 2001)
– records, e.g. date(day:17 month:decemeber year:2001)
• We can now add state to the fields
– arrays
– dictionaries
Seif Haridi and Peter Van Roy 28
Arrays
• An array is a mapping from integers to (partial) values
• The domain is a set of consecutive integers, with a lower bound and an upper bound
• The range can be mutated (change)
• A good approximation is to thing of arrays as a tuple of cells
Seif Haridi and Peter Van Roy 29
Operations on arrays
• A = {Array.new LB UB ?Value}
– Creates an array A with lower bound LB and upper bound UB
– All elements are initialized to Value
• There are other operations:
– To access and update the elements of the array
– Get the lower and upper bounds
– Convert an array to tuple and vice versa
– Check its type
Seif Haridi and Peter Van Roy 30
Example 1
• A = {MakeArray L H F}
• Creates an array A where for each index I is mapped to {F I}
fun {MakeArray L H F} A = {Array.new L H unit}in for I in L..H do A.I := {F I} end Aend
Seif Haridi and Peter Van Roy 31
Array2Record• R = {Array2Record L A}• Define a function that takes a label L and an array A, it
returns a record R whose label is L and whose features are from the lower bound of A to the upper bound of A
• We need to know how to make a record• R = {Record.make L Fs}
– creates a record R with label L and a list of features (selector names), returns a record with distict fresh variables as values
• L = {Array.low A} and H = {Array.high A}– Return lower bound and higher bound of array A
Seif Haridi and Peter Van Roy 32
Array2Recordfun {Array2Record LA A} L = {Array.low A} H = {Array.high A} R = {Record.make LA {From L H}}in for I in L..H do R.I = A.I end Rend
Seif Haridi and Peter Van Roy 33
Tuple to Array
fun {Tuple2Array T}
H = {Width T}
in
{MakeArray
1 H
fun{$ I} T.I end}
end
Seif Haridi and Peter Van Roy 34
Dictionaries (Hash tables)
• A dictionary is a mapping from simple values or literals (integers, atoms, amd names) to (partial) values
• Both the domain and the range can be mutated (changed)
• The pair consisting of the literal and the value is called an item
• Items can be added, changed and removed in amortized constant time
• That is to say n operations takes on average O(n)
Seif Haridi and Peter Van Roy 35
Operations on dictionaries
• D = {Dictionary.new}
– Creates an empty dictionary
• There are other operations:
– To access and update (and add) the elements of a dictionary using the ’.’ and ’:=’ notations
– Remove an item, test the memership of a key
– Convert a dictionary to a record and vice versa
– Check its type
Seif Haridi and Peter Van Roy 36
Indexed Collections
Tuple
Array Record
Dictionary
Add state Add atoms as indices
Add stateAdd atoms as indices
stateless collection
stateful collection
Seif Haridi and Peter Van Roy 37
Other collections
lists
streams
stacks
queues
potentiallyinfinite lists
stateless
ports
generalizesstreams to statefulmailboxes
stateless collection
stateful collection
Seif Haridi and Peter Van Roy 38
Encapsulated stateful abstract datatypes ADT
• These are stateful entities that can be access only by the external interface
• The implementation is not visible outside
• The are two method to build statefull abstract data types
• The functor based approach (record interface)
• The procedure dispatch approach
Seif Haridi and Peter Van Roy 39
The functor-based approach
fun {NewCounter I}
SS = {Record.toDictionary state(v:I)}
proc {Inc} S.v := S.v + 1 end
proc {Dec} S.v := S.v – 1 end
fun {Get} S.v end
proc {Put I} S.v := I end
proc {Display} {Show S.v} end
in o(inc:Inc dec:Dec get:Get put:Put show:Display)
end
Seif Haridi and Peter Van Roy 40
The functor-based approach
fun {NewCounter I}
SS = {Record.toDictionary state(v:I)}
proc {Inc} S.v := S.v + 1 end
proc {Dec} S.v := S.v – 1 end
fun {Get} S.v end
proc {Put I} S.v := I end
proc {Display} {Show S.v} end
in o(inc:Inc dec:Dec get:Get put:Put show:Display)
end
The state is collected in dictionary SThe state is completely encapsulatedi.e. not visible out side
Seif Haridi and Peter Van Roy 41
The functor-based approach
fun {NewCounter I}
SS = {Record.toDictionary state(v:I)}
proc {Inc} S.v := S.v + 1 end
proc {Dec} S.v := S.v – 1 end
fun {Get} S.v end
proc {Put I} S.v := I end
proc {Display} {Show S.v} end
in o(inc:Inc dec:Dec get:Get put:Put show:Display)
end
The interface is created for eachinstance Counter
Seif Haridi and Peter Van Roy 42
fun {NewCounter I}
SS = {Record.toDictionary state(v:I)}
proc {Inc} S.v := S.v + 1 end
proc {Dec} S.v := S.v – 1 end
fun {Get} S.v end
proc {Put I} S.v := I end
proc {Display} {Show S.v} end
in o(inc:Inc dec:Dec get:Get put:Put show:Display)
end
The functor-based approach
function that accessthe state by lexical scope
Seif Haridi and Peter Van Roy 43
Call pattern
declare C1 C2
C1 = {NewCounter 0}
C2 = {NewCounter 100}
{C1.inc}
{C1.show}
{C2.dec}
{C2.show}
Seif Haridi and Peter Van Roy 44
Defined as a functor
functor Counter
export inc:Inc dec:Dec get:Get put:Put show:Display init:Init
define
SS
proc {Init init(I)} SS = {Record.toDictionary state(v:I)} end
proc {Inc} S.v := S.v + 1 end
proc {Dec} S.v := S.v – 1 end
fun {Get} S.v end
proc {Put I} S.v := I end
proc {Display} {Show S.v} end
end
Seif Haridi and Peter Van Roy 45
Functors
• Functors have been used as a specification of modules
• Also functors have been used as a specification of abstract datatypes
• How to create a stateful entity from a functor?
Seif Haridi and Peter Van Roy 46
Explicit creation of objects from functors
• Given a variable F that is bound to a functor
• [O] = {Module.apply [F]}creates stateful ADT object O that is an instance of F
• Given the functor F is stored on a file ’f.ozf’
• [O] = {Module.link [’f.ozf]}creates stateful ADT object O that is an instance of F
Seif Haridi and Peter Van Roy 47
Defined as a functor
functor Counter
export inc:Inc dec:Dec get:Get put:Put show:Display init:Init
define
SS
proc {Init init(I)} SS = {Record.toDictionary state(v:I)} end
proc {Inc} S.v := S.v + 1 end
proc {Dec} S.v := S.v – 1 end
fun {Get} S.v end
proc {Put I} S.v := I end
proc {Display} {Show S.v} end
end
Seif Haridi and Peter Van Roy 48
Pattern of use
fun {New Functor Init}
[M] = {Module.apply [Functor]}
{M.init Init}
M
end
declare C1 C2
C1 = {New Counter init(0)}
{C1.inc} {C1.show}
{C2.inc} {C2.show}
Seif Haridi and Peter Van Roy 49
Example:memoization
• Stateful programming can be used to speed up declarative (functional) components by remembering previous results
• Consider the pascal triangle
• One way to make it faster between separate invocations is to remember previously computed rows
• Here follow our principle an change only the interna of a component
Seif Haridi and Peter Van Roy 50
Functions over lists
• Compute the function {Pascal N}
• Takes an integer N, and returns the Nth row of a Pascal triangle as a list
1. For row 1, the result is [1]
2. For row N, shift to left row N-1 and shift to the right row N-1
3. Align and add the shifted rows element-wise to get row N
111
1 2 1
1 3 3 1
1 4 6 4 1
(0) (0)
[0 1 3 3 1]
[1 3 3 1 0]
Shift right
Shift left
Seif Haridi and Peter Van Roy 51
fun {FastPascal N} if N==1 then [1] else local L in
L={FastPascal N-1} {AddList {ShiftLeft L} {ShiftRight L}}end
endend
Faster Pascal
• Introduce a local variable L
• Compute {FastPascal N-1} only once
• Try with 30 rows.
• FastPascal is called N times, each time a list on the average of size N/2 is processed
• The time complexity is proportional to N2 (polynomial)
• Low order polynomial programs are practical.
Seif Haridi and Peter Van Roy 52
Memoizing FastPascal• {FastPascal N} New Version
1. Make a store S available to FastPascal
2. Let K be the number of the rows stored in S (i.e. max row is the Kth row)
3. if N is less or equal K retrieve the Nth row from S
4. Otherwise, compute the rows numbered K+1 to N, and store them in S
5. Return the Nth row from S
• Viewed from outside (as a black box), this version behaves like the earlier one but faster
declare[S] = {Module.apply [StoreFun]}{S.put 2 [1 1]} {Browse {Get S 2}}{Browse {Size S}}
(see the program)
Seif Haridi and Peter Van Roy 53
The store functorfunctorexport put:Put get:Get size:Sizedefine S = {NewDictionary} C = {NewCell 0} proc {Put K X} if {Not {Dictionary.member S K}} then
{Assign C {Access C}+1} end S.K := X end fun {Get K} S.K end fun {Size} {Access C} endend
Seif Haridi and Peter Van Roy 54
The Pascal functor
functor PascalFun
import S at 'Store.ozf’ System
export
pascal:FastPascal
define
fun {FastPascal N} Definition of Pascal end
Definition of help procedures for Pascal {S.put 1 [1]}
end
Seif Haridi and Peter Van Roy 55
Memo pascal fun {FastPascal N} MaxRow in MaxRow = {S.size} if N =< MaxRow then
{S.get N} else L in
Compute the next N-MaxRow rows stating from row the value of MaxRow, call this list of rows L {PutList S MaxRow+1 L} {S.get N}
end end
Seif Haridi and Peter Van Roy 56
Memo pascal fun {FastPascal N} MaxRow in MaxRow = {S.size} if N =< MaxRow then
{S.get N} else L in
L = {PascalListNext N-MaxRow {S.get MaxRow}} {PutList S MaxRow+1 L} {S.get N}
end end
Seif Haridi and Peter Van Roy 57
The procedure dispatch approach
• Another method to realize stateful ADT is the procedure dispatch approach
• The instance of the ADT is a one argument procedure
• The procedure receives messages (when called)
• and dispatches to the right function according to the label of the message
• State is encapsulted
• The interface is defined as messages (implemented as records)
Seif Haridi and Peter Van Roy 58
The procedure-based approach
fun {NewCounter I}
SS = {Record.toDictionary state(v:I)}
proc {Inc inc} S.v := S.v + 1 end
proc {Dec dec} S.v := S.v – 1 end
proc{Get get(I)} I = S.v end
proc {Put put(I)} S.v := I end
proc {Display show} {Show S.v} end
D = o(inc:Inc dec:Dec get:Get put:Put show:Display)
in proc{$ M} {D.{Label M} M} end
end
Seif Haridi and Peter Van Roy 59
Call pattern
declare C1 C2C1 = {NewCounter 0}C2 = {NewCounter 100}
{C1 put(10)} {C1 inc} declare X {C1 get(X)}{C1 show}
{C2 dec}{C2 show}
Seif Haridi and Peter Van Roy 60
Declarative vs. Stateful
• We are going to study two different implementations of an algorithm, one using stateful data type representation and the other uses stateless representation
• The stateful representation will lead to a stateful (imperative) algorithm
• The stateless representation will lead to a declarative (functional) algorithm
• We start from the abstract description of the algorithm
Seif Haridi and Peter Van Roy 61
Transitive closure
• A directed graph consists of a set of vertices (nodes) V and a set of edges (represented as set of pairs of vertices) E
• (vi,vj) E iff there is an edge from vi to vj
2
1
4
3
65
{1,2,3,4,5,6}
{(1,2), (2,3), (3,4), (4,5), (5,6),(6,2) (1,2) }
The vertices
The edges
Seif Haridi and Peter Van Roy 62
Transitive closure
• Calculate a new graph TG, from the original graph G such that TG is the transitive closure of G
• That is to say there is an edge between a pair of nodes (i,j) in TG iff there is a path from i to j in the graph G
Seif Haridi and Peter Van Roy 63
Transitive closure
1
4
3
65
2
The set of immediate predecessors on node I, Pred(I)The set of immediate successors on node I, Suc(I)
Pred(2) = {1 6 5}Suc(2) = {3}
Seif Haridi and Peter Van Roy 64
The algorithm works by transforming the graph incrementally
1
4
3
65
21
4
3
65
2
Seif Haridi and Peter Van Roy 65
The algorithm works by transforming the graph incrementally
1
4
3
65
21
4
3
6
5
2
Seif Haridi and Peter Van Roy 66
The abstract algorithm
• For each node x in the graph G
– For each node y in Pred(x)
• For each node z in Suc(x) add the edge (y,z) to G
Seif Haridi and Peter Van Roy 67
The representation
• The representation dermines very much the model of implementation
• List (tree) based representation is suitable for declarative formulation
• Array (dictionary) based represntation is stuitable for a stateful formulation
Seif Haridi and Peter Van Roy 68
Representation
• The adjacency list representation
• The graph is a list of elements of the form I#Ns
• I is the node identifier, Ns is the list of successor nodes
• The matrix representation
• The graph is a two dimensional array GM, GM.I.J is true iff there is an edge from node I to node J
Seif Haridi and Peter Van Roy 69
Transitive closure
• The matrix representation• M is the matrix
K
IJ
M.I.K = true
L
M.K.J = trueM.L.K = false
Seif Haridi and Peter Van Roy 70
From abstract to concreteMatrix representation
• For each node K in the graph G
– For each node I in Pred(K)
• For each node J in Suc(K) add the edge (I,J) to G
proc {StateTrans GM}
L={Array.low GM}
H={Array.high GM}
in
for K in L..H do
For each in I in Pred(K) For each J in Suc(K) add GM.I.J := true
end
end
Seif Haridi and Peter Van Roy 71
From abstract to concreteMatrix representation
• For each node K in the graph G
– For each node I in Pred(K)
• For each node J in Suc(K) add the edge (I,J) to G
proc {StateTrans GM}
L={Array.low GM}
H={Array.high GM}
in
for K in L..H do
for I in L..H do if GM.I.K then
For each J in Suc(K) add GM.I.J := true end
end
end
Seif Haridi and Peter Van Roy 72
From abstract to concreteMatrix representation
proc {StateTrans GM}
L H ... in
for K in L..H do
for I in L..H do if GM.I.K then for J in L..M do if GM.K.J then GM.I.J := true
endend
end %% if
end %% for
end %% for
end
proc {StateTrans GM}
L={Array.low GM}
H={Array.high GM}
in
for K in L..H do
for I in L..H do if GM.I.K then
For each J in Suc(K) add GM.I.J := true end
end
end
Seif Haridi and Peter Van Roy 73
From abstract to concreteMatrix representation
proc {StateTrans GM}
L H ... in
for K in L..H do
for I in L..H do if GM.I.K then for J in L..M do if GM.K.J then GM.I.J := true
endend
end %% if
end %% for
end %% for
end
proc {StateTrans GM}
L={Array.low GM}
H={Array.high GM}
in
for K in L..H do
for I in L..H do if GM.I.K then
For each J in Suc(K) add GM.I.J := true end
end
end
Seif Haridi and Peter Van Roy 74
From abstract to concreteMatrix representation
proc {StateTrans GM}
L H ... in
for K in L..H do
for I in L..H do if GM.I.K then for J in L..M do if GM.K.J then GM.I.J := true
endend
end %% if
end %% for
end %% for
end
proc {StateTrans GM}
L H ... in
for K in L..H do
for I in L..H do if GM.I.K then for J in L..M do GM.I.J := GM.I.J orelse GM.K.J end end %% if
end %% for
end %% for
end
Seif Haridi and Peter Van Roy 75
Transitive closureadjacency lists
1
4
3
65
2
[ 1 # [2] 2 # [1 3] 3 # [4] 4 # [5] 5 # [2] 6 # [2]]
The immediate successor list is sorted,e.g. 2 # [1 3]
Seif Haridi and Peter Van Roy 76
From abstract to concreteAdjacency list representation
• For each node X in the graph G
– For each node Y in Pred(X)
• For each node Z in Suc(X) add the edge (Y,Z) to G
fun {DeclTrans G}
Xs = {Nodes G} in
{FoldL Xs fun {$ InG X}
SX = {Suc X} For each node Y in Pred(X)
For each Z in SX add edge (Y,Z)
end
G}
end
G0, {F G0 X0} , {F {F G0 X0} X1}, ...
This is {FoldL Xs F G0}
Seif Haridi and Peter Van Roy 77
From abstract to concreteAdjacency list representation
fun {IncPath X SX InG}
{Map InG
fun{$ Y#SY}
Y#If Y in Pred(X) then
{Union SY SX} else SY end
end}
end
fun {DeclTrans G}
Xs = {Nodes G} in
{FoldL Xs fun {$ InG X}
SX = {Suc X} For each node Y in Pred(X)
For each Z in SX add edge (Y,Z) in GC
end
G}
end
For each node Y in PX For each Z in SX add
edge (Y,Z) in GC
Seif Haridi and Peter Van Roy 78
From abstract to concreteAdjacency list representation
fun {IncPath X SX InG}
{Map InG
fun{$ Y#SY}
Y#If {Member X SY} then
{Union SY SX} else SY end
end}
end
fun {DeclTrans G}
Xs = {Nodes G} in
{FoldL Xs fun {$ InG X}
SX = {Suc X} For each node Y in Pred(X)
For each Z in SX add edge (Y,Z) in GC
end
G}
end
Y in Pred(X) if and only if X in Pred(Y)
Seif Haridi and Peter Van Roy 79
Conclusion
• The stateful algorithm was straight forward in this case• The declarative algorithm was a bit harder• Both algorithms are of O(n3)• In the declarative algorithm we assume Successor list is
sorted• Union is just implemented by mergeing sorted lists O(n)• We exploited the fact that Y in Pred(X) if and only if X in
Pred(Y)
• The declarative one is better if the graph is sparse (many elements in the martix are ’false’)
Seif Haridi and Peter Van Roy 80
System building
• Abstraction is the best tool to build complex system
• Complex systems are built by layers of abstractions
• Each layer have to parts:
– Specification, and
– Implementation
• Any layer uses the specification of the lower layer to implement its functionality
Seif Haridi and Peter Van Roy 81
Properties needed to support the principle of abstraction
• Encapsulation
– Hide internals from the interface
• Compositionality
– Combine parts to make new parts
• Instantiation/invocation
– Create new instances of parts
Seif Haridi and Peter Van Roy 82
Component base programming
• Supports
– Encapsulation
– Compositionality
– Instantiation
Seif Haridi and Peter Van Roy 83
Object-oriented programming
• Supports
– Encapsulation
– Compositionality
– Instantiation
• Plus
– Inheritance
Seif Haridi and Peter Van Roy 84
Component-based programming
• ”Good software is good in the large and in the small, in its high level architecture and in its low-level details”. In Object-oriented software construction by Bernard Meyer
• What is the best way to build big applications?
• A large application is (almost) always built by a team
• How should the team members communicate?
• This depends on the application’s structure (architecture)
• One way is to structure the application as a hierarchical graph
Seif Haridi and Peter Van Roy 85
Component-based programming
Interface
Component instance
Externalworld
Seif Haridi and Peter Van Roy 86
Component based design
• Team members are assigned individual components
• Team members communicate at the interface
• A component, can be implemented as a record that has a name, and a list of other component instances it needs, and a higher-order procedure that returns a component instance with the component instances it needs
• A component instance has an interface and an internal entities that serves the interface
Seif Haridi and Peter Van Roy 87
Model independence priciple
• As the system evolves, a component implementation might change or even the model changes– declarative (functional)– stateful sequential– concurrent, or– relational
• The interface of a component should be independent of the computation model used to implement the component
• The interface should depend only on the externally visible functionality of the component
Seif Haridi and Peter Van Roy 88
Example:memoization
• Consider the pascal triangle
• One way to make it faster between separate invocations is to remember previously computed rows
• Here follow our principle an change only the interna of a component
Seif Haridi and Peter Van Roy 89
What happens at the interface?
• The power of the component based infrastructure depends on large extent on the expressiveness of the interface
• How does components communicate with each others?
• We have three possible case:
– The components are written in the same language
– The components are written in different languages
– The components are written in different computation model
Seif Haridi and Peter Van Roy 90
Components in the same language
• This is easy
• In Mozart/Oz component instances are modules (records whose fields contain the various services provided by the component-instance part
• In Java, interfaces are provided by objects (method invocations of objects)
• In Erlang component instances are mainly concurrent processes (threads), communication is provided by sending asynchronous messages
Seif Haridi and Peter Van Roy 91
Components in different languages
• An intermediate common language is defined to allow components to communicate given that the language provide the same computation model
• A common example is CORBA IDL (Interface Definition Language) which maps a language entity to a common format at the client component, and does the inverse mapping at the service-provider component
• The components are normally reside on different operating system processes (or even on different machines)
• This approach works if the components are relatively large and the interaction is relatively infrequent
Seif Haridi and Peter Van Roy 92
Illustration (one way)
A component C1calling the function (method) f(x) in theComponent C2
Translate f(x) fromlanguage L1 (structured data) to IDL (sequence of bytes)
Translate f(x) fromlanguage IDL (sequence of bytes) tolanguage L2 (structured data)
A component C2 invoking the function (method) f(x)