Title: More Flexible Software By Favoring Implicit Calls and Implicit Communication
1More Flexible Software By Favoring Implicit
Callsand Implicit Communication
- by Karl Lieberherr
- Joint work with Bryan Chadwick, Ahmed Abdelmeged
and Therapon Skotiniotis
2What we want
well-accepted
- Data Abstraction Principle the implementation of
objects can be changed without affecting clients
provided the interface holds. - Adaptive Programming Principle
the interface of objects can be changed without
affecting clients provided adaptive constraints
hold.
3- can abstract traversal code
- non-cyclic objects
- explicit and implicit cyclic objects cause
problems
4Abstraction boundaries
- M consists of (interfaceM, implementationM) so
that interfaceM(implementationM). implementationM
can be changed to implementationM provided
interfaceM(implementationM). - M2 uses M1.
5Abstraction boundaries
- M consists of (faceM, mentM) so that
faceM(mentM). mentM can be changed to mentM
provided faceM(mentM). - (faceM2,mentM2) uses (faceM1,mentM1). mentM2
relies on faceM1 which changes to faceM1.
Implementation of M2 defines constraints on M1.
6Module
- Consists of Interface and Implementation.
Implementation imports other modules. - AdaptiveConstraints Constraints on imported
modules.
7Module Interface Implementation
uses
module M2
module M1
faceM1 mentM1
faceM2 mentM2
uses
faceM1 mentM1
faceM1 mentM12
faceM1 mentM1
faceM1 mentM13
change implementation
change interface
8Module Interface Implementation
AdaptiveConstraints
uses (imports)
module M2
module M1
faceM1 mentM1
faceM2 mentM2 AdapConM1
uses (imports)
faceM1 mentM1
module M1
faceM1 mentM12
faceM1 mentM1
faceM1 mentM13
change implementation
change interface
AdapConM1(M1)
9What Hinders Creation of Flexible Software
- Rigidly following rules like Follow the
structure, follow the grammar. - Actively call traversal methods (explicit
traversal problem). - Also leads to manual passing of arguments
(explicit argument problem).
10Alternative 1 AP-F
- Think of computation as moving or pushing up
information in an object (combine methods). - Allow transformation at each node (apply
methods). - Send information down as needed (update methods).
- Default behavior copy object.
11Alternative 2 AP-P
- Think of computation as traversing the object and
collecting information in a visitor object. - Use both regular visitor variables as well as
interposition variables. - Interposition variables facilitate implicit
communication. - Default behavior traverse object.
12AP-F implemented in Java by DemeterF
- Examples plan
- apply only
- apply and combine
- apply and combine and update
13Type Unifying information flow
T combine(A a, T t)
X update(A a, X x)
A
object graph
T apply(T t) T combine(B b, T t1, T t2)
B
X update(B b, X x)
C
D
T apply(T t) T combine(C c, T t1)
T apply(D d, X x)
E
T apply(E e, X x)
14Type Unifying information flowno update
T combine(A a, T t)
A
object graph
T apply(T t) T combine(B b, T t1, T t2)
B
C
D
T apply(T t) T combine(C c, T t1)
T apply(D d)
E
T apply(E e)
15Type Unifying information flowno update
T combine(A a, T t)
A
object graph
T apply(T t) T combine(B b, T t1, T t2)
B
C
D
T apply(T t) T combine(C c, T t1)
T apply(D d)
E
T apply(E e)
16Type Unifying information flowno update
T combine(A a, T t)
A
object graph
T apply(T t) T combine(B b, T t1, T t2)
B
C
D
T apply(T t) T combine(C c, T t1)
T apply(D d)
E
T apply(E e)
17Type Unifying information flowno update
T combine(A a, T t)
A
object graph
T apply(T t) T combine(B b, T t1, T t2)
B
C
D
T apply(T t) T combine(C c, T t1)
T apply(D d)
E
T apply(E e)
18Type Unifying information flowno update
T combine(A a, T t)
A
object graph
T apply(T t) T combine(B b, T t1, T t2)
B
C
D
T apply(T t) T combine(C c, T t1)
T apply(D d)
E
T apply(E e)
19Type Unifying information flowno update
T combine(A a, T t)
A
object graph
T apply(T t) T combine(B b, T t1, T t2)
B
C
D
T apply(T t) T combine(C c, T t1)
T apply(D d)
E
T apply(E e)
20Type Unifying information flowno update
T combine(A a, T t)
A
object graph
T apply(T t) T combine(B b, T t1, T t2)
B
C
D
T apply(T t) T combine(C c, T t1)
T apply(D d)
E
T apply(E e)
21Type Unifying information flow
combine(a,apply(combine(b,apply(combine(c,apply(e,
x))),
apply(d,x))))
T combine(A a, T t)
X update(A a, X x)
A
object graph
T apply(T t) T combine(B b, T t1, T t2)
B
X update(B b, X x)
C
D
T apply(T t) T combine(C c, T t1)
T apply(D d, X x)
E
T apply(E e, X x)
22Type Preserving information flow
A combine(A a, B b)
X update(A a, X x)
A
object graph
B apply(B b) B combine(B b, C c, D d)
B
X update(B b, X x)
C
D
C apply(C c) C combine(C c, E e)
D apply(D d, X x)
E
E apply(E e, X x)
23Type Preserving information flow
combine(a,apply(combine(b,apply(combine(c,apply(e,
x))),
apply(d,x))))
A combine(A a, B b)
X update(A a, X x)
A
object graph
B apply(B b) B combine(B b, C c, D d)
B
X update(B b, X x)
C
D
C apply(C c) C combine(C c, E e)
D apply(D d, X x)
E
E apply(E e, X x)
24semantics apply-combine expression
Tree ltngt Node ltleftgt Tree
ltrightgt Tree. Node IdentityApply
ltogt Object.
- apply(combine(this,
- apply(combine(left,)),
- apply(combine(right,))
- ))
- Translate tree object into apply-combine
expression.
25Traversal semantics
26Default Transformercopy object
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
27Parameterize Default Transformer
PathSpec apply(J j) return new
Complement(j)
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
28Parameterize Default Transformer
PathSpec combine(J j, Boolean fn, Boolean sn)
return fn sn
PathSpec combine(Object j, Boolean fn, Boolean
sn) return fn sn
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
29Simple applicationProgram transformation
- Old
- E Num Var Op Call
- Op Plus Equals.
- Equals .
- New
- E Bool.
- Bool True False.
class BoolTrans extends IDf static E newtrue
Call.parse(( 1 1)), static E newfalse
Call.parse(( 1 0) ) E apply(True t) return
newtrue E apply(False t) return newfalse
apply for transformation of result returned by
builder
30de Bruijn indices
for later
- Old
- Var Sym.
- Sym Ident.
- New
- Var Sym Addr.
- Addr Integer.
class AddrTrans extends IDf Var apply(Var
var, SymList senv) return new
Addr(senv.lookup(var)) class SymExtender
extends IDa SymList update(Lambda l, SymList
senv) return senv.push(l.formals)
31The default Builder for PathSpec
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
32well-formed movie
- show how the default builder is modified to
combine Boolean objects.
33The default Builder for PathSpecwell-formed
specialization 1
t true f false
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
t
5
2
S
S
S
S
7
8
t
t
t
3
4
t
34The default Builder for PathSpecwell-formed
specialization 2
t true f false
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
t
t
5
2
S
S
S
S
7
8
t
t
t
3
4
t
35The default Builder for PathSpecwell-formed
specialization 3
t true f false
after blue arrow copy is built (like after)
10
t
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
t
t
t
3
4
t
36The default Builder for PathSpecwell-formed
specialization 4
t true f false
after blue arrow copy is built (like after)
10
t
M
1
9
J
6
t
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
t
t
t
3
4
t
37The default Builder for PathSpecwell-formed
specialization 5
t true f false
after blue arrow copy is built (like after)
10
t
M
1
9
J
6
t
t
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
t
t
t
3
4
t
38The default Builder for PathSpecwell-formed
specialization 6
t true f false
after blue arrow copy is built (like after)
10
t
f
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
t
t
t
3
4
t
39The default Builder for PathSpecwell-formed
specialization 7
f
t true f false
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
t
t
t
3
4
t
40The default Builder for PathSpecwell-formed
specialization
t true f false
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
t
t
t
3
4
t
41The default Builder for PathSpecNOT_JOIN_MERGE
specialization
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
42The default Builder for PathSpecNOT_JOIN_MERGE
specialization
S
means a copy
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
43The default Builder for PathSpecNOT_JOIN_MERGE
specialization
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
44The default Builder for PathSpecNOT_JOIN_MERGE
specialization
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
45The default Builder for PathSpecNOT_JOIN_MERGE
specialization
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
46The default Builder for PathSpecNOT_JOIN_MERGE
specialization
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
47The default Builder for PathSpecNOT_JOIN_MERGE
specialization
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
48The default Builder for PathSpecNOT_JOIN_MERGE
specialization
after blue arrow copy is built (like after)
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
49The default Builder for PathSpecNOT_JOIN_MERGE
specialization
insert NOT
after blue arrow copy is built (like after)
N
10
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
50The default Builder for PathSpecNOT_JOIN_MERGE
specialization
N
insert NOT
M
after blue arrow copy is built (like after)
N
10
N
M
1
9
J
6
Count only upon first visit (red) and upon final
visit (blue). For leaf nodes, count only in red.
J
5
2
S
S
S
S
7
8
3
4
51Illustration of combinefor capacity constraint
violation
19a
19
C
(w1w2w3w4,2)
Cons
(w1w2w3w4,1)
E
(w4,0)
1
20
2
18a
3
18
3a
13a
(w1w2w3,1)
Cons
after blue arrow combine is active (like after)
17a
C
(w2w3,1)
4
12a
17
Cons
(w1,0)
5
13
14
12
16a
(w2w3,0)
Cons
15a
6
(0,0)
E
Empty
(w1,0)
11a
7a
15
16
11
E
(w3,0)
Cons
(w2,0)
both containers (C) violate capacity constraints
8
7
10a
9a
(w2,0)
E
Empty
(0,0)
9
10
52Illustration of combinefor capacity constraint
violation
C
(w1w2w3w4,2)
Cons
(w1w2w3w4,1)
E
(w4,0)
(w1w2w3,1)
Cons
C
(w2w3,1)
Cons
(w1,0)
(w2w3,0)
Cons
(0,0)
E
Empty
(w1,0)
E
(w3,0)
Cons
(w2,0)
both containers (C) violate capacity constraints
(w2,0)
E
Empty
(0,0)
53Theory
On left side of gt the term c() only indicates a
compound object.
f apply b combine
- tf,b(d) gt d, where df(d), d is atomic
- tf,b(c(d0, ,dn)) gt
- f(b(c(d0, ,dn), d0, ,dn)), where di
tf,b(di) - Default functions
- idf(d) gt d
- idb(c(d0, ,dn), d0, ,dn) gt c(d0, ,dn)
- bc(c(d0, ,dn), d0, ,dn) gt c(d0, ,dn)
54Theory
- f is a polymorphic function that takes a single
argument and returns a result. - b is a function object that is responsible for
reconstruction of data types.
55Traversal Component Approach
- implemented in DemeterF
- Traversal with 3 components Builder (combine),
Transformer (apply), Augmentor (update)
56Augmentors / update methods
- so far we covered combine and apply methods
- combine to combine information up the object
- apply to transform before the information is
sent up. - up refers to the traversal when a traversal has
finished visiting an object, it goes up. - add update, to send information down the object
- if it's not used/needed, it does not need to be
mentioned, since the traversal will do the
passing around.
57motivating exampleAddress computation
- Var Sym Addr.
- Addr Integer.
- class AddrTrans extends IDf
- Var apply(Var var, SymList senv)
- return new Addr(senv.lookup(var))
- class SymExtender extends IDa
- SymList update(Lambda la, Symlist senv)
- return senv.push(la.formals)
58Optional argument
- The argument passed into the traversal (by the
programmer) is available everywhere (in
everyapply/combine/update function) but it may
be needed only in some objects. - In the typechecker case is only needed when
looking up a variable use, or modifying the
type-environment with a binding.
59Like a let for subtraversals
- An update argument can be viewed (almost) as a
'let' for sub-traversals before traversing
sub-terms we do a recalculation of the traversal
argument. Update is called before traversing sub
terms, and themodified value is only available
for sub terms.
60Structure-shy passing of argument
- If you look at the Scheme code you would write to
traverse the same structure you would pass
alongan argument to the functions, all the way
through recursive calls until it is needed. At a
lambdathe recursive call on the body would look
something like (type-Lambda l tenv)
(cases Exp l (Lambda (arg body)
(type-Exp body (tenv-extend tenv arg)))
(Call (op arglist) (let ((ret
(type-Exp op tenv)) ...) (... other
cases...)))
61Default passing it alongno code needed with
DemeterF
- Note that we don't change the traversal argument
in most cases, only when binding an argument to a
type. Usually we just keep passing it along
throughout the traversal functions. The
augmentor/update methods encapsulate (only) the
changes of this argument, so we simply write - TEnv update(Lambda l, TEnv te)
- return te.extend(l.formal)
- The traversal takes care of the default case when
we don't need to change the argument.
62All arguments are optional
- All arguments are now optional... thus the most
general method is Object combine() return
... Since it is applicable in all cases (all
arguments optional, including the 'traversal
argument').(the traversal argument is the one
updated by update methods. There is only one
traversal argument)
63AST illustration
- Call --- Lambda --- Arg
--- Type ---
int ---
Sym --- 'a'
--- Call ---
Plus --- Sym
--- 'a'
--- Num --- 2 ---
Num --- 4
Update is called at each label and the Object
returned is then available to all terms
'connected'and to the right of that label.
64Technical Details
- Methods you want to call determine from where you
inherit ID (all), IDa (update), IDb (combine),
IDba (combine, update), IDf (apply), IDfa (apply,
update), IDfb(apply, combine).
65Motivation
- Showing a full scheme type-checking function, and
highlighting the points wherethe
type-environment is passed, used, and extended.
The number of cases where it is just passed
along motivates the want/need to put the
modifications in one place, and being able to
ignore theargument when it's not really needed.
66Traversal
67What is shy code?
- Shy code shouldnt reveal too much of itself and
shouldnt be too nosy into others affairs. - Law of Demeter only talk to your friends