Title: Is DJ sound compared to Java?
1Is DJ sound compared to Java?
- A comparison of effort and static analysis
support when working with DJ and OO
2Motivation
- DJ has the AI flavor that it automatically
transforms programs when the context (class
graph) changes. - Some people see this power as a danger.
- We point out that when a proper software
engineering process is followed there is no
danger. - Powerful tools can be used in bad ways.
3Motivation
- Some people feel that DJ cannot give the same
static error messages as OO tools. We show that
this is not the case. - Some people feel that DJ does not save any effort
because the code needs to be tested after a class
graph change. This is like saying high-level
languages are bad. First address this point.
4DJ programs are intentionally kept general
Class graph 1
DJ program (only methods)
Class graph 2
Class graph 3
5DJ programs are intentionally kept general
Class graph 1 correct behavior
DJ program with constraints
Class graph 2 incorrect behavior
Class graph 3 rejected
6DJ programs are intentionally kept general
Class graph 1 correct behavior
DJ program with constraints
Class graph 2 incorrect behavior
Distinction between and
requires testing
7High-level control of oo program structure is
important
- From A to B selects paths with 50 edges
- From A via X to B selects path with 10 edges
- Small change big effect
- Once strategy correct, traversal guaranteed to be
correct. - Hand-coding of traversal is source of errors
8What does DJ save during evolution? Terminology.
- Class graph G1 and traversal specification S1 for
behavior B. - Requirements change need to change G1 to G2. In
general we might have to change traversal
specification S1 to S2 to achieve desired
behavior B. Note - S1 is not necessarily a strategy it could be an
English specification that says how to traverse
G1-objects.
9What does DJ save during evolution? Terminology.
- T(G,S) traversal methods for G and S.
- S is not necessarily a strategy it could be an
English specification that says how to traverse
G-objects. - TG(G,S) traversal graph for G and S.
- Compatible(G,S) Is G compatible with S? For all
edges (x,y) in S there is a path in G from x to y.
10What does DJ save during evolution? Terminology.
- Diff(TG1, TG2), Diff(T(G1, S1), T(G2, S2)) list
differences for each node. - Errors(G2,T(G1,S1))) compiler error messages
- Errors(G2, G1) if G1 has an edge (A,B) then G2
has such an edge, otherwise report error.
11For AP library (used by DJ)
- Errors(G2, G1) if G1 has an edge (A,B) then G2
has such an edge, otherwise report error.
12What does DJ save during evolution?
Written by user
Inspected by user, generated by compiler
- Both Class graphs G1 and G2. Traversal methods
T(G1,S1) and T(G2,S2) to be tested. - DJ Strategy graphs S1, S2. Traversal graphs
TG(G1,S1) simulating T(G1,S1) and TG(G2,S2)
simulating T(G2,S2). Compatible(G2,S2).
Errors(G2, Graph(TG(G1,S1))). Diff(TG(G1,S1), TG
(G2,S2)). - OO T(G1,S1) and T(G2,S2). Compatible(G2,T(G2,S2))
. Errors (G2,T(G1,S1)). Diff(T(G1,S1), T(G2,S2)).
13Comparing DJ versus OO during evolution effort
Written by user
Inspected by user, generated by compiler
- AP
- S1,TS ? S2
- Compatible(G2,S2)
- Errors(G2, Graph(TG(G1,S1)))
- Diff (TG(G1,S1), TG(G2,S2))
- OO
- T(G1,S1),TS ? T(G2,S2)
- Compatible(G2,T(G2,S2))
- Errors(G2,T(G1,S1))
- Diff (T(G1,S1), T(G2,S2))
Common G1 ? G2, test(T(G1,S1)), test(T(G2,S2)),
traversal change specification
TS Comparable effort testing DJ less effort
on average
14Comparing DJ versus OO during evolution static
checking
Written by user
Inspected by user, generated by compiler
- AP
- S1,TS ? S2
- Compatible(G2,S2)
- Errors(G2, Graph(TG(G1,S1)))
- Diff (TG(G1,S1), TG(G2,S2))
- OO
- T(G1,S1),TS ? T(G2,S2)
- Compatible(G2,T(G2,S2))
- Errors(G2,T(G1,S1))
- Diff (T(G1,S1), T(G2,S2))
Common G1 ? G2, test(T(G1,S1)), test(T(G2,S2)),
traversal change specification
TS Comparable information
15Example
S1
A
C
S2
A
B
C
A
B
C
K
A
B
C
G1
G2
X
K
A
B
C
A
B
C
T(G1,S1)
T(G2,S2)
AP
OO
A
B
C
Errors
A
B
C
Errors
K
K
C
C
A
B
A
B
Diff
Diff
16Example
- S1 from A to C
- G1A,BB,C
- T(G1)A B C
- Compatible yes
- Errors no B,C
- Diff B,CgtB,K. new K,C
- S2 from A via B to C
- G2A,BA,XB,KK,CX,C
- T(G2) A B K C
- Compatible yes
- Errors no B,C
- DiffB,CgtB,K. new K,C
17Comparison DJ versus OO during evolution
- Static analysis information
- DJ gives similar static information as OO
- Evolution effort
- DJ never worse than OO
- in many cases DJ less effort
- Danger of wrong traversals testing needed.
- OO possibility of errors not detected
statically. - DJ possibility of strategy being wrong. But if
strategy correct, traversal guaranteed to be
correct.
18Comparison DJ versus OO during evolution
- If class graph changes, it is necessary to
re-test the program. - Whether program is hand-coded or specified
through strategies, it needs to be tested.
19Abusing DJ
- No retesting after class graph change. Reusing a
piece of software (e.g., a strategy) in a new
context (a new class graph) requires retesting.
Antidecomposition adequacy rule (Weyuker) - There exists a program P and a component Q of P
such that T is adequate for P, T' is the set of
vectors of values that variables can assume on
entrance to Q for some t of T and T' is not
adequate for Q.
P
Q
20Application to DJ
- Adaptive program Q used in program P (determined
by a class graph and Q). - If P is adequately tested, Q might not be
adequately tested.
P
Q
21Abusing DJ
- Ignoring Errors() and Diff() output because the
new program compiles and runs. Uncritical
acceptance of the analogical transformation done
by DJ.
22Programming in DJ
- Can avoid any direct access to a part program
becomes elastic.
23Computing your class graph
- ClassGraph cg new ClassGraph()//.java
- // Need to do once
24Instance-variable-free programming
- Rule for eliminating instance variable access
- // A a new A()
- // bb a.get_b()
- bb (B) cg.fetch(a, new
- Strategy(A-gtB))
25Gathering objects
- Collecting B-objects reachable from A
- Vector bb cg.gather(a, new
- Strategy(A-gtB))
26DJ example
- ClassGraph cg new ClassGraph()//.java
- A a new A()
- cg.traverse(a, new Strategy
- (A-gtB, new MyVisitor())