defense

Document Sample
scope of work template
							Interface-Oriented Programming
and Representation Inference



    L. Robert Varney
    June 1, 2005
Agenda

   Introduction
   Motivating Problems
   Solution
   Implementation
   Experiments
   Related Work
   Conclusion
Introduction
The Concept

              B                                          C
                                new
                           A           B           new        new
    extends


                                                     A        B
              A


    OO software decomposition and recomposition
     mechanisms are plagued by four problems that impair
     design quality, reusability, safety, and evolvability
        Implementation Bias (Concrete Dependencies)
        Feature Combinatorics (Inability to Factor Designs)
        Representation Assembly (Unsafe Assembly of Factored
         Design Elements)
        Representation Selection (Performance/Reusability
         Tradeoff in Choosing an Implementation of an Interface)
The Concept

              B                                     C
                            new
                        A          B          new       new
    extends


                                                A       B
              A


    The first three problems can be solved by pervasive use
     of interfaces together with automatic assembly guided
     by locally specified, interface-oriented constraints.
    The last problem is harder, but we can avoid embedding
     the tradeoff in the code, and separately employ an
     automatic mechanism for good, context-dependent
     representation choices.
Contributions

   IOP as a programming paradigm that
    solves the four important problems
   PJ, an example of an IOP language
   Representation Inference, a novel
    mechanism for software assembly
   A pervasive, language-integrated
    factory mechanism based on
    representation instantiation graphs, a
    means for context-dependent evolution
    of representation choices
Since Last Time We Met …

   Name change and other revisions to the
    IOP language
       Was “ARC”, now “PJ”
   Formalized the safety objectives the IOP
    system should guarantee
   Finished a prototype implementation of
    the compiler, representation inference
    engine, and run-time system that
    together support the development of
    representative examples.
Motivating
Problems
Motivating Problems

   Implementation Bias
   Feature Combinatorics
   Representation Assembly
   Representation Selection
Problem 1: Implementation Bias

   Dependence on concrete
    implementations where abstractions
    should suffice
   Caused in OOP by use of class names at
    instantiation dependencies (new object
    creation, implementation inheritance)
Forms of Implementation Bias

   class C extends ClassName { … }

   X obj = new ClassName();

       Both are commitments to concrete
        implementations at locations of
        instantiation dependency
Why Do We Want to Avoid This?



    Client           CCName          CCImpl         CCImpl+


   Lacking an explicit interface, we may assume
    that the client depends on some uknown subset
    of the concrete class implementation’s closure
       This is unstable and out of the client’s control …
       A bad situation – some middle ground should be sought
        and made explicit
Problem 2: Feature Combinatorics

   Difficulty of factoring the design of a
    library of components
   Goals:
       No code replication
       Span feature space
       Low coupling between components
       Separate client-relevant from implementation
        details
Example: A Feature Space for Sets and Bags

   Implementation Framework:
       Particular set of private abstract methods to be
        implemented according to some core data structure
   Choice of core data structure:
       Trees, lists, hashtables, etc.
   Null Values Allowed?
       Yes, No
   Element Equality?
       By value, by identity
   Element Storage?:
       Story copy, store reference
   Element Uniqueness?
       Unique, non-unique
Single Inheritance Implementation
                                     Choice of
          Choice of                  framework
          core data
          structure
Other
feature
choices




                      Not all combinations are legal,
                      and ordering matters …
Multiple Inheritance or Mixin-Class
Implementation

No more code replication …




    But someone needs to compose the bottom row correctly …
    And ordering still matters …
Problem 3: Representation Assembly


   Difficulty of assembling partial
    implementations into correct, robust, complete
    representations
   Goals:
       No knowledge of encapsulated information
       Get exactly what you want, and it stays that way
   Special cases of this problem:
       Multiple Inheritance Conflicts
       Fragile Base Class Problem
       Intrusiveness of Aspect-Weaving, Fragile Pointcuts
The Fragile Base Class Problem
class Stack {
   void push(int x)
   { … }
   void pushAll(int[] x) {
      … push(e); …
   }
   …
}

class CountedStack
  extends Stack {
   int count;
   void push(int x) {
      super.push(x);
      count++;
   }
   …
}
The Fragile Base Class Problem
class Stack {                class Stack {
   void push(int x)             void push(int x)
   { … }                        { … }
   void pushAll(int[] x) {      void pushAll(int[] x) {
      … push(e); …                 …
   }                            }
   …                            …
}                            }

class CountedStack
  extends Stack {
   int count;
   void push(int x) {
      super.push(x);
      count++;
   }
   …
}
The Fragile Base Class Problem
                        class Stack {
                           void push(int x)
                           { … }
                           void pushAll(int[] x) {
                              …
                           }
                           …
                        }

class CountedStack      class CountedStack
  extends Stack {         extends Stack {
   int count;              int count;
   void push(int x) {      void push(int x) {
      super.push(x);          super.push(x);
      count++;                count++;
   }                       }
   …                       void pushAll(int[] x) {
}                             super.pushAll(x);
                              count += x.length;
                           }
                           …
                        }
The Fragile Base Class Problem
class Stack {                class Stack {
   void push(int x)             void push(int x)
   { … }                        { … }
   void pushAll(int[] x) {      void pushAll(int[] x) {
      … push(e); …                 …
   }                            }
   …                            …
}                            }

                             class CountedStack
                               extends Stack {
                                int count;
                                void push(int x) {
                                   super.push(x);
                                   count++;
                                }
                                void pushAll(int[] x) {
                                   super.pushAll(x);
                                   count += x.length;
                                }
                                …
                             }
Problem 4: Representation Selection

   Selecting the best implementation of an
    interface
   Goals:
       Maximal reusability for the component using the
        interface
       Good performance in all execution contexts
   But:
       Interface abstraction breaks link between context and
        implementation
       No Free Lunch – impossible to pick one
        implementation that outperforms all others in all
        contexts.
Example:
A Map-based
Application
                        Information only
                        available here …   Example:
                                           A Map-based
What kind
of Map?                                    Application




            What kind
            of Array?




                 What kind                 May determine
                 of ArrayPolicy?           the best answers
                                           here …
Solution
Solution Elements

   Interfaces Everywhere
   Particles: Unbiased Partial Classes
   Representation Inference
   Method and Type Constraints
   Pervasive Factory Mechanism
   Representation Instantiation Graph (RIG)
Solution Elements:

Interfaces and Particles
    Interfaces
interface B1 {                    interface B2 {

    B1(int b); // constructor         B2(double x); // constructor

    void b1(); // method              void b2(); // method
}                                 }


             interface I extends B1, B2 {

                 I();           // constructor

                 void i();      // method
             }

             B1 b1 = new B1(0);       // instantiation

             B2 b2 = new B2(9.9); // instantiation

             I i = new I();           // instantiation
    Particles: Unbiased Partial Classes

particle P represents I assumes B1, B2 {

     int v;                         // instance variable

     I() assumes B1(0), B2(9.9) {
         …                          // constructor impl.
     }

     void i() {
         … b1(); … b2(); …          // method impl.
     }

     void b1() {
         … super.b1(); …            // refined method impl.
     }
}
 Interface-Oriented Relationships
                                        T

                                Interface Lattice
                                     extends
I x = new I();

                 I1            Im                B1             Bn
 Client                ….                               ….
                 a()                                            b()




                  represents                          assumes

                                    particle P

                            void a(){ .. b(); .. }
 Example: A Stack

                          interface Collection<T> {
                              …
                              boolean empty();
                              …
                          }




interface Stack<T>                        interface List<T>
  extends Collection<T> {                   extends Collection<T> {
    Stack<T>();                               List<T>();
    void push(T x);                           void addRear(T x);
    T pop();                                  T removeRear();
    T top();                                  T rear();
    void pushAll(Collection<T> c);            …
}                                         }
Multiple Stack Particles


  particle PSi represents Stack<T> assumes Stack<T>, List<T> {
      Stack<T> assumes Stack<T>(), List<T>() { }
      void push(T x) { addRear(x); }
                              Collection<T>
      T pop() { return removeRear(); }
      T top() { return rear(); }
                     S
      void pushAll(Collection<T> c) uses push(T);
  }



                    Stack<T>                 List<T>
  particle PSall represents Stack<T> assumes Stack<T> {
      void pushAll(Collection<T> c) {
          for (T x in c.elements()) A
                                    push(x);
      }
  }
Another Stack Particle



      particle PSiArr
        represents Stack<T> assumes Stack<T>, Array<T> {
          Stack<T>() assumes Stack<T>(), Array<T>() { }
          void push(T x) { add(x); }
          T pop() { return remove(size()-1); }
          T top() { return get(size()-1); }
          void pushAll(Collection<T> c) uses push(T);
      }
Solution Element:

Representation Inference
Representation Inference

   Assembles particles into complete representations of
    interfaces
   Generates multiple alternative representations for each
    interface instantiation site in a program
   Resolves inheritance dependencies
   A candidate representation for some interface is:
     A sequence of particles

     … with an associated constructor sequence

     … and inter-particle method and constructor bindings

   A candidate representation is a representation if it:
     Completes the interface

     Completes all of the particles in the sequence

     Method bindings and type attributes satisfy all particle
       constraints
Dependencies of the Stack Example
                                                      extends

             Collection<T>         ?                  represents
                                   .
                                   .                  represents,
                                                      assumes
                                   .
                                                      assumes



            PS

Stack<T>    PSi          List<T>       ?   Array<T>             ?
                                       .                        .
           PSall
                                       .                        .
           PSiArr                      .                        .
             .
             .
             .
   Looking at PSi another way …

                                                          Collection<T>()
                                  Collection<T>           Iter<T> elements()
                                                          boolean contains(T)                Interface-oriented
                                                          boolean empty()                  inheritance provides
                                                          int size()
                                                                                              implicit virtual
                                                                                                base types.
             extends                            extends              extends


                                                                                               Multiple base
                                                                                             abstractions are
  Stack<T>                            Stack<T>                           List<T>             merged before
               Stack<T>()                   pushAll(Collection<T>)        List<T>()          representations
               push(T)                                                    addRear(T)
               T pop()                                                    T removeRear()
                                                                                                are inferred,
               T top()                                                    T rear()                avoiding
                                                                                                inheritance
represents                        assumes
                                                                                             anomalies but
                                                               assumes
                                                                                            allowing multiple
                                                                                              inheritance of
                            PSi
                                                                                                   state.
   PSall …

                                                         Collection<T>()
                                 Collection<T>           Iter<T> elements()
                                                         boolean contains(T)
                                                         boolean empty()
                                                         int size()




             extends                           extends              extends




  Stack<T>                            Stack<T>
             pushAll(Collection<T>)         Stack<T>()
                                            push(T)
                                            T pop()
                                            T top()



represents                        assumes



                           PSall
   Unifying: PSi + PSall + rep(List<T>())

                                                    Collection<T>()
                                                    Iter<T> elements()
                                                                                      rep(List<T>())?
                                    Collection<T>
                                                    boolean contains(T)
                                                    boolean empty()
                                                    int size()




             extends                                           extends


                                                                                       Only consistent
                                                                                       representations
  Stack<T>                                                          List<T>              are combined
                 Stack<T>()
                 push(T)                                             List<T>()          (automatically),
                                                                     addRear(T)
                 T pop()
                                                                     T removeRear()
                                                                                          avoiding the
                 T top()
                                                                     T rear()         fragile base class
                 pushAll(Collection<T>)
                                                                                         problem, but
represents
                                                                                        without violating
                                                          assumes
                                                                                        encapsulation.
                              PSi

                              PSall
Inferred Stack Representations

   List-based family of representations:

     rep(Stack<T>())  PSi + PSall + rep(List<T>())




   Array-based family of representations:

     rep(Stack<T>())  PSiArr + PSall + rep(Array<T>())
Solution Elements:

Methods and Type Constraints
Encapsulated Method Constraints
   Constraints encapsulated in particles, not in interfaces

   Used by representation inference to determine inclusion of a particle
    (or not) and what method bindings are legal

   Method overriding constraints:
       initial methods – may always be replaced
       essential methods – a group of methods in one particle that may not be
        individually replaced unless the replacing method refines it using
        super.meth()
       final methods – may not be replaced
       Method implementations are essential by default

   Method use constraints:
       void foo() uses bar();
       void super.foo() !uses bar();

   “Use” is based on transitive closure of method bindings across a
    representation (not control flow)
Type Attribute Constraints

   Positional type parameters, named role types, and named
    properties
   Upper bound constraints may be expressed in both
    interfaces and particles
   The constraints expressed in interfaces and particles for
    the same type attribute may be different
   Interfaces may refine the attribute constraints of their
    ancestors or introduce new attributes
   Particles may only refine the attribute constraints of the
    interfaces they represent and assume, they may not
    introduce new attributes
   A representation is required to have a solution to these
    constraints
Example: Properties for Set/Bag Behaviors


   interface Collection {
      …
      property equality = {value, identity};
      property nullsAllowed = {yes, no}
      property store = {copy, reference};
      property membership = {unique, nonunique};
   }



   interface Set extends Collection {
      …
      property Collection::membership = {unique};
   }
Example: Properties for Set/Bag Behaviors
       particle PBagAddNA
          represents Collection
          assumes Collection, Collection as Insert
          …
          property Collection::membership = {nonunique};
          property Collection::nullsAllowed = {yes};

           void add(T x) {
              insert(x);
           }
       }


       particle PSetAdd
          represents Collection
          assumes Collection, Collection as Insert
          …
          property Collection::membership = {unique};
          property Collection::nullsAllowed = {no};

           void add(T x) {
              if (x != null && !contains(x)) {
                 insert(x);
              }
           }
       }
Solution Elements:

Pervasive Factory Mechanism
A Pervasive, Language-Integrated
Factory Mechanism
   Implements instantiation of interface X:

                        obj = new X();


   using a RepNode and an Instantiator:

        // Get client particle’s RepNode
        rn = getRepNode();

        // Get instantiator for this instantiation site
        instantiator = rn.getInstantiator(seg,siteK);

        // Construct the object
        obj = instantiator.construct_X();
Implementation
PJ System Architecture
PJ Compiler Front-End
Representation Inference Engine
Representation Inference:
A Naïve Algorithm
inferRepsNaive( C ) {

    RSet = empty;

    for (PPerm in Permutations(AllParticles)) {

        for (CtorPerm in CtorPermutations(PPerm)) {

            for (MethodBindings in Bindings(PPerm,CtorPerm)) {

                R = makeRep(PPerm,CtorPerm,MethodBindings);

                if (representsType(C) && complete(R) && satisfied(R)) {

                    RSet = RSet + R;
                }
            }
        }
    }

    return RSet;
}
Representation Inference:
Revisions to the Naïve Algorithm

   Iteratively construct a particle sequence,
    constructors, and method bindings
   Work bottom up, inferring descendants before
    ancestors, selecting undefined methods for a
    minimal interface at each step
   Check constraints at each iteration, use
    backtracking search
   Also use constraints to direct the search, e.g.:
       Attempt to split downcalls that violate constraints
Representation Instantiation Graph

     I0           I1                I2             I3
                                                                Defaults




  I0=RX                            I2=RA                I2=RB




          Back edge to a                   I3=RM
              Default      I0,2
                                                            Context
                                                            Dependent
                                                            RepNodes

                                  I0=RY        I0=RY
Context-Dependent, Evolvable
Representation Selection via RIGs
   RepNode:
       A data structure governing the choice of representation for some instantiation site (or
        sites) in a program. RepNodes are grouped into “trees” with occasional back-edges to the
        root of other RepNode trees.

   A Default RepNode:
       A root of a RepNode “tree”

   RIG (Representation Instantiation Graph):
       A forest of RepNode “trees”

   Context dependence:
       The path to a particular RepNode provides a form of context. The same lexical instantiation
        site may correspond to multiple RepNodes corresponding to different dynamic instantiation
        contexts.
       The RepNode “trees” in a RIG are bounded in depth but can be arbitrarily deep (user
        control)

   Evolvability:
       RIGs can be manipulated without changing source code
       Still, manipulated RIGs always chooses representations safely
RepNodes                 RepNode

                              __ci__Foo__0    Refers to instantiator
                                              for constructor __ci__Foo
   Each RepNode is
    responsible for           0    1     2     Segments
    managing an
                            0 1 2 0 1 0 1 Instantiation sites
    instantiator for some
    representation, and
    knows about the
                                              obj = new X();
    instantiation sites in
    that representation
   For each instantiation          RepNode
    site, it may refer to a
    child repNode or to a                 __ci__X__0
    default repNode in
    the program’s                        0           1
    genotype                         0 1 2 3 0 1 2
RepNodes and Instantiators

                                                                     MetaInstantiator
           __ci__Foo__0


       0                   1               2
   0   1       2       0       1       0       1           Instantiator        Rep__Foo__K




                                                                          MetaInstantiator

                           __ci__X__0


                       0                           1                                Rep__X__J
                                                              Instantiator
           0       1       2       3       0       1   2
 Object Instantiation Protocol


     :Client                :Client                :Rep            :Site                      :Meta
                                                                                                          :Instantiator
    Particle                RepNode              Genotype         RepNode                  Instantiator



new X
         getInstantiator(seg,k)

                                  New RepNode?
                                                            new

                                                                       getInstantiator(ciName)     Meta
                                                                                                   Inst.
                                                                                                   Protocol




                                                                            instantiator

                                                      siteRepNode

                                      siteRepNode


                                  getInstantiator()


                                  instantiator
          instantiator


          construct_X()

          object
   Instantiator Meta-Instantiation Protocol

                      :Meta                             :Context   :Instantiator   :Instantiator
                   Instantiator                         Database      Options         Binding



getInstantiator(ciName)

                          lookupOptions(ciName)



                          instantiatorOptions



                          chooseInstantiatorBinding()


                          instantiatorBinding



                          getInstantiator()
                                                                                           Load Rep Class
                                                                                           Create Instantiator



                          instantiator
Experiments
Experiment 1:

A Stack
Visualizing Representation Inference
                                             Start with all methods of interface undefined …

                                Defined Methods

                                                     Collection(0)::empty()
                                                      Stack(0)::push(int);
                              Undefined Methods     Stack(0)::pushAll(int[])
                                                        Stack(0)::pop()
                                                        Stack(0)::top()




 Result of merging PXList …


 Stack(0)::top() = seg(PXList,0)
 Stack(0)::pop() = seg(PXList,0)                          Stack(0)::push(int)
 Stack(0):push() = seg(PXList,0)
                                                          = PXList

        Collection::empty()
       Stack::pushAll(int[])                      Chosen undefined method
        List(0/1)::addTail()                      and chosen particle that defines it
      List(0/1)::removeTail()
        List(0/1)::getTail()
Inference results
For Stack
Inference results
For Stack
Experiment 2:

Another Stack (FBC version)
The Fragile Base Class Problem, Again
class Stack {                class Stack {
   void push(int x)             void push(int x)
   { … }                        { … }
   void pushAll(int[] x) {      void pushAll(int[] x) {
      … push(e); …                 …
   }                            }
   …                            …
}                            }

class CountedStack           class CountedStack
  extends Stack {              extends Stack {
   int count;                   int count;
   void push(int x) {           void push(int x) {
      super.push(x);               super.push(x);
      count++;                     count++;
   }                            }
   …                            void pushAll(int[] x) {
}                                  super.pushAll(x);
                                   count += x.length;
                                }
                                …
                             }
Robust Stack Particles
particle PX                             particle PY
   represents Stack                        represents Stack
   assumes Stack, … {                      assumes Stack {

    void push(int x) { … }                  void pushAll(int[] x) {
    int pop() { … }                            … push(e); …
    int top() { … }                         }
    …                                       …
}                                       }



                 particle PZ
                   represents Stack {
                    void push(int x) { … }
                    void pushAll(int[] x) { … }
                    int pop() { … }
                    int top() { … }
                 }
Robust Counted Stack Particles

 particle CS2              particle CS1
   represents Stack          represents Stack
   assumes Stack {           assumes Stack {

     int count;                int count;

     void push(int x) {        void push(int x) {
        super.push(x);            super.push(x);
        count++;                  count++;
     }                         }

     void pushAll(int[])       void pushAll(int[] x) {
     uses push(int);              super.pushAll(x);
                                  count += x.length;
     …                         }
 }
                               void super.pushAll(int[])
                               !uses push(int);
                               …
                           }
Split downcall
Experiment 3:

A Set Library Design
Inference results
For Set with just one
Core data structure option (X1)
Inference results
For Set with four
Core data structure options,
Each with different constraints
Experiment 4:

A Map
particle PMain represents Main {
   …
   void main(String[]) {

        Map m1 = new Map();
        // … use m1 one way

        Map m2 = new Map();
        // … use m2 some other way

        Map m3 = new Map();
        // … use m3 yet another way
    }
    …
}
An Evolved RIG for
the Map application
Experiment 5:

An Artificial Ant
An Artificial Ant

   Problem:
       Evolve an artificial ant
        behavior that can
        navigate a path
        through a grid,
        consuming all the
        food
       A benchmark
        problem of Genetic
        Programming [Koza]
Traditional GP
Non-Terminals and Terminals

               if (foodAhead())                left()




                   then   else                 right()




      progn2                      progn3
                                               move()



  1            2            1       2      3
Artificial Ant Interfaces in PJ
                       interface Ant {
                           void init(Grid g);
                           void lookForFood();
                           boolean foodAhead();
                           void move();
                           void left();
                           void right();
                           boolean alive();
                       }


                       interface Behavior {
                           void behave();
                       }




  interface DecideBehavior                interface Action
     extends Behavior {                      extends Behavior {
  }                                       }
Artificial Ant Particle


            particle PBasicAnt represents Ant {

                Behavior behavior;
                …
                Ant() {
                    behavior = new Behavior();
                }
                …
                void lookForFood() {
                    while (alive()) {
                        behavior.behave();
                    }
                }
            }
  Ant Behavior Particles
particle PDecideBehavior               particle PLeftAction
    represents Behavior {                  represents Action {
    …                                      …
    void init( Ant a ) {                   void init( Ant a ) {
        ant = a;                               ant = a;
        foodAction = new Action();             nextBehavior = new Behavior();
        noFoodAction = new Action();       }
    }                                      void behave() {
    void behave() {                            ant.left();
        if (foodAhead()) {                     nextBehavior.behave();
            ant.move();                    }
            foodAction.behave();       }
        }
        else {
            noFoodAction.behave();
        }                              particle PRightAction
    }                                      represents Action {
}                                          …
                                       }


particle PEmptyAction                  particle PMoveAction
    represents Action {                    represents Action {
    …                                      …
}                                      }
An Evolved RIG for
the Artificial Ant
Related Work
Related Work

   Explicit recomposition methods
   AOP
Explicit (Manual) Recomposition

   Approaches:
     Generative programming [Czarnecki], feature-oriented
      programming [Batory], Mixin-Layers [Smaragdakis]
     Single inheritance, Multiple inheritance

     Mixin-classes [Bracha90][Flatt98], Traits [Scharle03]



   The class-composer must know:
     The class dependency graph

     The internals of each class

     The mapping from client interface requirements to
      implementing classes
     How to assemble classes together



   The class-composer must hope:
     That things don’t change after composition
Explicit (Manual) Recomposition
vs. Representation Inference

   Explicit recomposition:
       Human guesses a solution (a partial order on class
        increments) using knowledge of an explicit class
        dependency graph and implicit class
        interdependencies


   Representation Inference:
       There is no class graph; constraints are explicit in
        particles
       Provides multiple alternative solutions (particle
        sequences) automatically
       “No Assembly Required”
AOP vs. IOP

   AOP and Aspect-Weaving [Kiczales97]:
       Targets cross-cutting concerns, not base component decomposition
       Requires fragile knowledge of implementation class naming conventions and
        internal statement patterns (implementation bias)
       Invasively modifies bodies of methods that are oblivious to the invasion
       Both compile-time and run-time modifications
       Requires global reasoning to determine correctness

   IOP and Representation Inference:
       Targets concern decomposition in general, though not currently able to factor
        some concerns that AOP can handle
       Requires knowledge of interface names and semantics
       Affects only explicit method call sites and inheritance dependencies
       Not a run-time mechanism
       Local reasoning

   Recent trends in AOP are towards the use of interfaces to control
    and reason about the effect of aspects !
       [Kiczales05], [Aldrich05]
Conclusion
Summary
   IOP enables improvements to the design
    quality, reusability, safety, and evolvability of
    software artifacts when compared to OOP.
   IOP accomplishes this via:
       Ubiquitous interfaces that remove implementation
        bias
       Partial class particles that enable fine-grained design
        decomposition and avoid code replication
       Automatic, safe, and robust inference of complete
        representations
       A pervasive factory mechanism that dynamically binds
        interfaces to inferred representations, enabling
        context-dependent evolvability of representation
        choices without source code modifications
 A Spectrum of Paradigms

                           IOP


          GP                            OOP


    Underbiased                     Overbiased

  Expected behavior              Expected behavior
    of an interface                of an interface
is ill-defined (IKIWISI)         is well-understood

 Generic interfaces              Specific interfaces
  admitting MANY                   admitting FEW
  representations                 representations
Future Work
   Finish implementation of key features:
     Type parameters and parametric representation inference

     Roles, anchors, and collaboration inference

   Investigate possibility that IOP can subsume most of AOP
    via addition of abstract method types?
   Improve representation inference algorithm (e.g.,
    incremental use of previously inferred representations)
   Improve evolvability through better RIG search algorithms,
    evolvable representation constants, etc.
   Industrial strength implementation, Eclipse tool support,
    etc., needed to attempt larger experiments
END
BACKUP SLIDES
A Java Example: List
interface List {
    void add(int x);
    int remove();
    int remove(int pos);
    int get();
    int size();
    …
}
public class ArrayList implements List {
    …
    ArrayList() { … }
    void add(int x) { … }
    int remove() { … }
    int remove(int pos) { … }
    int get() { … }
    int size() { … }
    …
}
A Java Example: Stack
interface Stack {
    void push(int x);
    int pop();
    int top();
    boolean empty();
}


public class StackImpl extends ArrayList implements Stack {
    StackImpl() { … }
    void push(int x) { … }
    int pop() { … }
    int top() { … }
    boolean empty() { … }
}
A Java Example: A Client of
StackImpl
      public class Client {
          …
          Client() {
              …
          }
          void method() {
              …
              StackImpl s = new StackImpl();
              …
              s.remove(0);
              …
          }
          …
      }
A Java Example: A Client of
Stack
      public class Client {
          …
          Client() {
              …
          }
          void method() {
              …
              Stack s = new StackImpl();
              …
              s.remove(0); // ERROR
              …
          }
          …
      }
Another Stack
Implementation
   public class StackImpl2 implements Stack {

       List list;

       StackImpl( List l ) { list = l; }

       void push(int x) { … }
       int pop() { … }
       int top() { … }
       boolean empty() { … }
   }
Another Client of Stack

  public class Client {
      …
      Client() {
          …
      }
      void method() {
          …
          Stack s = new StackImpl2(new ArrayList());
          …
          s.remove(0); // ERROR
          …
      }
      …
  }
Categories Problems   Causes
Problems   Causes   Solutions
OLD SLIDES
Problem

   Philosophical Assumption:
       Large-scale software development requires types, static
        type checking, incremental programming support (e.g.,
        inheritance), and dynamic binding. This is provided to
        some degree by current object-oriented programming
        languages.
   Problem:
       Existing programming languages force early commitment
        to particular implementations, which impairs our ability
        to reuse code and evolve systems noninvasively.
Problems
   Implementation Selection Problem:
       Occurs when the best choice of implementation for some interface used by a client
        may depend on the context of the client, which varies.
           Example: Client must select StackImpl
   Trapped Implementation Bias Problem:
       Occurs when the choice of implementation for an interface is statically embedded
        within the client.
           Example: Cannot change choice of StackImpl without changing
            Client
   Implementation Composition Problem:
       Occurs when the client must select multiple mutually compatible implementations
        and compose them together.
           Example: Client needs to compose StackImpl2 with
            ArrayList
Solution
Solution

   Interface-Oriented Programming Approach
   Interface-Oriented Programming in ARC
   Benefits and Costs of ARC
   Representation Inference
   Interface-Oriented Collaborations in ARC
Basic Idea

   In true object-oriented programming, everything
    is an object.
   In interface-oriented programming, everything is
    an interface. What this really means is that:
       All non-local dependencies between program
        fragments are expressed in terms of abstract
        interfaces.
Interface-Oriented Programming
Approach
   Identify interface semantics with abstract interface names by convention.
   Clients depend only on the abstract interfaces which provide the
    semantics they require.
   Allow multiple implementations of any abstract interface.
   When implementing an abstract interface, the representation should
    depend only on abstract interfaces for lower-level services required
    (whether inherited, contained, or used).
   When implementing an abstract interface, separate the abstraction being
    represented for clients from the abstractions needed internally due to the
    local design of the representation.
   Define representations incrementally – separate partial representations
    which make different local assumptions.
   When a composition of implementations is needed, clients should specify
    a composition of interfaces.
Interface-Oriented Programming
in ARC:
- Abstractions
       abs A extends A1,…,An {

           // Constructor Interfaces
           A();
           …

           // Method Interfaces
           …
       }
Interface-Oriented Programming
in ARC:
- Representations assumes SA1,…,SAm {
     rep R represents A1,…,An

         // Instance Variables
         VA1 v1;
         …
         VAk vk;

         // Constructors
         A1() { … }
         …
         An() { … }

         // Methods
         …
     }
Interface-Oriented Programming
in ARC:
- Non-Deterministic
Instantiation assumes X {
         rep R …
           …
           void method() {
               …

               A object = new A();

               …
           }
           …
       }
An ARC Example: Stack
  abs Stack {                   abs List {
      Stack();                      List();
      void push(int x);             void add(int x);
      int pop();                    int remove();
      int top();                    int remove(int pos);
      boolean empty();              int get();
  }                                 int size();
                                    …
                                }

  rep StackImpl represents Stack assumes List {
      Stack() assumes List() { ; }
      void push(int x) { add(x); }
      int pop() { return remove(); }
      int top() { return get(); }
      boolean empty() { return size() == 0; }
  }
An ARC Example: A Client of
Stack
     rep ClientRep represents Client … {
         …
         Client() {
             …
         }
         void method() {
             …
             Stack s = new Stack();
             …
             s.remove(0); // ERROR
             …
         }
         …
     }
Summary of ARC Concepts
   Separation of interfaces from implementations:
       abs vs. rep
   Multiple implementations per interface:
       rep R1 represents A …
       rep R2 represents A …
   Interface-oriented multiple inheritance for client interfaces:
       abs A extends A1,…,An …
   Interface-oriented multiple inheritance for specialization:
       rep R … assumes SA1,…,SAm …
   Interface-oriented variable references:
       All variables typed with abstraction names
   Non-deterministic Instantiation:
       A object = new A();
The Benefits of ARC
   Encourages programming style where representations make
    minimal assumptions. This minimizes trapped
    implementation bias and maximizes reusability of
    representations.
   Enables incremental programming style where
    representations may provide partial implementations based
    on hidden assumptions. Separately defined partial
    representations can be mixed and matched provided their
    respective local assumptions are satisfied consistently.
   Provides interface-oriented composition of
    implementations.
The Costs of ARC
   System must correctly link together partial
    representation fragments to provide a complete
    representation for an abstract interface. This
    requires a new kind of “linker”.
   Complete representation solution not necessarily
    unique. This implies:
         The need to provide some way to select from available candidate
          representations.
         The opportunity to tune representations automatically by
          selecting different representations from the space of solutions.
Representation Inference

   A new kind of program linking …
   Inference of a complete representation for an
    abstract interface by assembling multiple partial
    representations automatically.
   The external and internal interface dependencies of
    a partial representation are constraints which must
    be satisfied by the complete representation.
   Generates one or more solutions, one of which
    must be selected.
Representation Inference
Example           abs C {
                      void c1();
                      void c2();
                  }




   abs A extends C {           abs B extends C {
       void a1();                  void b1();
       void a2();                  void b2();
       void a3();                  void b3();
   }                           }




               abs D extends A, B {
                   void d1();
               }
Representations of A, B, C, and D
 rep RC represents C {              rep RD represents D assumes A, B {
     …                                  …
     void c1() { … }                    void c1() { … }
     void c2() { … }                    void c2() { … }
 }                                  }



                                                rep RB1 represents B {
 rep RA1 represents A assumes C {                   …
     …                                              void c1() { … }
     void a1() { … }                                void c2() { … }
     void a2() { … }                                void b1() { … }
     void a3() { … }                                void b2() { … }
 }                                                  void b3() { … }
                                                }


 rep RA2 represents A {
     …
     void c1() { … }                  rep RB2 represents B assumes C {
     void c2() { … }                      …
     void a1() { … }                      void b1() { … }
     void a2() { … }                      void b2() { … }
     void a3() { … }                      void b3() { … }
 }                                    }
Representation Constraints
           RC  { d(C) = e(RC) }

          RA1  { d(A) = e(RA1) }

   RA2  { d(A) = e(RA2), d(C) = e(RA2) }

   RB1  { d(B) = e(RB1), d(C) = e(RB1) }

          RB2  { d(B) = e(RB2) }

           RD  { d(D) = e(RD) }
Representation Solutions

         Solution 1   Solution 2   Solution 3

  d(C)    e(RC)       e(RA2)       e(RB1)

  d(A)   e(RA1)       e(RA2)       e(RA1)

  d(B)   e(RB2)       e(RB2)       e(RB1)
  d(D)    e(RD)        e(RD)        e(RD)
Interface-Oriented Programming
in ARC:
- Collaboration Abstractions {
abs C extends A1,…,An { abs R1 within C
                                      …
    collaboration {                   void foo( role Rr );
        role R1;                  }
        …
        role Rr;                  …
    }
                                  abs Rr within C {
    // Constructors and Methods       …
    …                                 void bar( role R1 );
    void meth1( role R1 );        }
    void meth2( role R2 );
    …
}
Interface-Oriented Programming
in ARC:
- Representations within
    rep R1 represents A1,…,An within C
Collaborations                assumes SA1,…,SAm
                              with role R2 as SA2
                                …
                                with role Rr as SAr {

          // Instance Variables, Constructors, Methods
          …
      }
Graph Collaboration: Client Abstractions
        abs Graph {
            collaboration {
                role Vertex;
                role Edge;
            }
            …
            control Iterator<role Edge> edges();
            control Iterator<role Vertex> vertices();
        }


        abs Vertex within Graph {
            …
            int getValue();
            control Iterator<role Edge> edges();
        }


        abs Edge within Graph {
            …
            role Vertex getVertex1();
            role Vertex getVertex2();
        }
Graph Collaboration: Specialization
Abstractions

      abs IndexedVertex extends Vertex within Graph {
          …
          int setIndex(int index);
          int getIndex()
      }



      abs IndexedVertexGraph extends Graph {
          …
          int getMaxVertices();
          role Vertex getVertex(int index);
          int getIndex(role Vertex);
      }
Partial Graph Representation:
Vertices Indexed
rep RIndexedVertexGraph represents IndexedVertexGraph assumes Graph
                        with role Vertex as IndexedVertex {

    // representation of vertex collection as array of vertices

    Array<role Vertex> va;
    …
    role Vertex getVertex( int index ) {
        return va[index];
    }

    int getIndex( role Vertex v ) {
        return v.getIndex();
    }
    …
}
Partial Graph Representation:
Connectivity as Adjacency Matrix
rep RMatrixGraph represents Graph assumes IndexedVertexGraph
                        with role Vertex as IndexedVertex {

    // representation of connectivity as adjacency matrix

    Matrix<boolean> matrix;
    …
    control Iterator<role Edge> edges() {
        …
    }

    control Iterator<role Vertex> adjacentVertices() {
        …
    }
    …
}
Partial Graph Representation:
Connectivity as Array of Adjacency
Lists
rep RListGraph represents Graph assumes IndexedVertexGraph
                        with role Vertex as IndexedVertex {

    // representation of connectivity as array of adjacency lists

    Array<MutableSeq<role Vertex>> lists;
    …
    control Iterator<role Edge> edges() {
        …
    }

    control Iterator<role Vertex> adjacentVertices() {
        …
    }
    …
}
Graph Collaboration: Coloring
Abstractions

      abs ColoredVertex extends Vertex within Graph {
          …
          int setColor(int c);
          int getColor()
      }




      abs ColoredGraph extends Graph {
          …
          void computeMinColoring();
          int getColor(role Vertex);
      }
Partial Graph Representation:
Graph Coloring
rep RColoredGraph represents ColoredGraph assumes Graph
                        with role Vertex as ColoredVertex {
    …
    void computeMinColoring() {
        …
        for (role Vertex v in vertices()) {
            …
            v.setColor( c );
            …
        }
    }
    int getColor( role Vertex v ) {
        return v.getColor();
    }
    …
}
Graph Collaboration: Matching
Abstractions

      abs MatchedEdge extends Edge within Graph {
          …
          void setMatched(boolean matched);
          boolean isMatched()
      }




      abs MatchedGraph extends Graph {
          …
          void computeMinMatching();
          int isMatched(role Edge);
      }
Partial Graph Representation:
Graph Matching
rep RMatchedGraph represents ColoredGraph assumes Graph
                        with role Vertex as ColoredVertex {
    …
    void computeMinMatching() {
        …
        for (role Edge e in edges()) {
            …
            e.setMatched( true );
            …
        }
    }
    boolean isMatched( role Edge e ) {
        return e.isMatched();
    }
    …
}
Interface-Oriented Composition of
Colored and Matched Graph
Abstractions
final [ColoredGraph,MatchedGraph] cmg = new [ColoredGraph(),MatchedGraph()];
…
cmg.computeMinColoring();
cmg.computeMinMatching();
…
for (cmg.Vertex v in cmg.vertices()) {
    …
    int color = cmg.getColor(v);
    …
}
…
for (cmg.Edge e in cmg.edges()) {
    …
    boolean matched = cmg.isMatched(e);
    …
}
…
Inferred Representations


[ColoredGraph, MatchedGraph]    role Vertex      role Edge




    RIndexedVertexGraph           RVertex          REdge

RListGraph or RMatrixGraph     RIndexedVertex   RMatchedEdge

       RColoredGraph           RColoredVertex

       RMatchedGraph
Contributions
Main Contributions

   Invention of the concept of Interface-Oriented
    Programming (IOP).
   Design of ARC, a novel class-based language which
    supports IOP and includes advanced support for
    object-oriented and collaboration-based design.
   Non-deterministic instantiation and representation
    inference.
Other Contributions
(Planned, or Not Discussed Here)
   Constructor assumptions and constructor blending.
   New approaches for control abstraction and
    exception handling needed for IOP.
   Segmented object model for IOP which provides
    constant-time dynamic dispatch for interfaces.
   Plan: Assessment of development environment
    support needed for IOP.
   Plan: Assessment of different techniques for
    representation selection.
Related Work
Related Work
(Selected Topics – See Prospectus for More
Details)
   Interfaces, Implementations, and Inheritance
   Factories
   Mixins
   Traits and Habitats
   Feature-oriented programming
   Dual-ported component approaches
Extending IOP to handle Aspects

   Method types:
     particle PModelUpdate
        represents ModelUpdate
        assumes ModelUpdate, DisplayUpdate {

         …

         void modelUpdate() {
            super.modelUpdate();
            displayUpdate();
         }

         super.modelUpdate() !uses displayUpdate();
     }
Interfaces, Implementations, and
Inheritance
[Sny86b], [AvdL90], [CCHO89], [CP89], [CHC90], [KL92],
 Interface inheritance (subtyping) distinct from
[Coo92], [Lam93]
    implementation inheritance (subclassing) and
    should be kept separate.
   Specializers (implementation reusers) need a
    different interface than clients (implementation
    users).
   No known language allows clients or specializers
    requiring instantiation to be independent of a
    particular implementation.
Factories
[Cop92], [LS94], [Rie95], [GHJV95]

   Programming idioms for creating objects which
    hides the name of the class being instantiated from
    the requestor of the object.
   As a programming technique, requires anticipation
    of the need for factories.
   Works only on whole representations.
   Works only for clients, no equivalent support for
    specializers.
   Requestor must know the name of the factory
    implementation (or parameterize it).
Mixins
[BC90], [FKF98]

   Abstract subclasses – classes which inherit from
    undefined base classes.
   MIXEDJAVA:
       Provides interface-oriented inheritance to define mixin
        implementations (the undefined bases are interfaces).
       Only supports no-arg constructors.
       Clients must compose mixins by hand and reference
        mixin implementations by name.
       Cannot use mixins with unbound base interfaces to
        create objects.
Traits and Habitats
[RL89], [SDNB03]

   Similar to mixins, but for class internals only.
   Macro-like techniques for defining the internals of a
    class in terms of method fragments. Thus, supports
    low-level description of partial representations.
   Programmer must compose method fragments
    together, and supply dependencies (e.g., accessor
    methods for instance variables).
Feature-Oriented Programming
[Pre97]

   A “feature” is like a class but:
       Implements an interface (not part of the feature; defined
        separately).
       Defines core functionality separate from its interaction with other
        features
   Features represent implementations. To use a feature, must
    refer to the feature (implementation) by name.
   Client must compose feature implementations manually.
   Feature composition exposes entire interface to each
    feature, which violates encapsulation of the composition in
    certain cases.
   Interactions limited to two features at a time
Dual-Ported Component
Approaches
[CL01], [CP02], [MO02]
   Component model based on two interface ports to a
    component:
       Provided interface – the interface to main component
        functionality
       Required interface – the interface the component expects of its
        environment
   Typically separates implementation from interfaces.
   Client must compose implementations of both provided
    and required interfaces together.
   Exposure of required interface exposes implementation
    bias.
   Nested class approach suffers from feature combinatorics
    problem.
Status and Plan
Status

   Key ideas formulated and tested “on paper”:
       Interface-oriented programming
       Non-deterministic instantiation
       Representation inference and selection
       Segmented object model
   ARC language design substantially complete, but need to
    integrate contexts and parametric types.
   ARC compiler under development.
   Completed initial assessment of approach relative to other
    work.
Plan
   Establish baseline formal definition of ARC (including support for
    contexts and parametric types), and design complete algorithm for
    representation inference.
   Implement for a subset of ARC:
     Representation Inference Mechanism (RIM) in Java

     Representation Selection Mechanism (RSM) in Java

     Segmented Object Model (SOM) in Java

     Compilation of ARC into Java

     Interactive development environment in Java

   Apply ARC subset to example software design problems.
   Explore alternatives for improving representation selection.
   Complete overall evaluation of interface-oriented programming relative to
    established approaches to software development, and assess requirements
    for an IOP development environment.
 Schedule
 Complete ARC Language Baseline Definition




 ARC Subset Implementation




        ARC Application, Representation Selection Work, IOP Tool Requirements



                                    Complete Dissertation




Summer 03        Fall 03       Winter 04       Spring 04     Summer 04          Fall 04
The End
BACKUP SLIDES
Implementation-Oriented Programming
Program Construction
              Compile
                         Compiled
                         Modules

             Link/Load

                         Loaded
                         Program
               Run
Interface-Oriented Programming
Program Construction
                Compile
 Compiled
Partial Reps

               Represent *

                             Infer
                                      Complete
               Link/Load                Reps

                             Select

                  Run
Implementation-Oriented vs. Interface-
Oriented
Program Construction
Implementation-Oriented:

  Client  ImplName  MachineAddress




Interface-Oriented:

                    INFER              SELECT
  Client  InterfaceName  {Impl1,…,ImplN}  ImplK  MachineAddress
Segmented Object Model
                     SegmentIndex   MethodPtr
Instance
                     SegmentIndex   MethodPtr
 InstanceTable
                          …             …
  Segment 0
                     SegmentIndex   MethodPtr
  Segment 1

      …
  Segment K
                 Segment 0
                                            SegmentIndex   MethodPtr
                   SegmentTable
                                            SegmentIndex   MethodPtr
                     InstanceVar
                                                 …             …
                         …
                                            SegmentIndex   MethodPtr
                     InstanceVar

                 …
                 Segment K
                                            SegmentIndex   MethodPtr
                   SegmentTable
                                            SegmentIndex   MethodPtr
                     InstanceVar
                                                 …             …
                         …
                                            SegmentIndex   MethodPtr
                     InstanceVar
Dynamic Dispatch: External
Casefunc() {
 void
     …
     x.foo();
     …
 }


 void func( Instance self, Segment seg) {
     …
     Instance xself = self.var[X];
     int k = xself.table.segment[SEG_FOO];
     Segment xseg = xself.seg[k];
     xself.table.method[METH_FOO].call( xself, xseg );
     …
 }
Dynamic Dispatch: Internal
Casefunc() {
 void
     …
     bar();
     …
 }


 void func( Instance self, Segment seg) {
     …
     int k = seg.table.segment[SEG_BAR];
     Segment barseg = self.seg[k];
     seg.table.method[METH_M1].call( self, barseg );
     …
 }
Representation Instantiation Graph

     I0           I1                I2             I3
                                                                Defaults




  I0=RX                            I2=RA                I2=RB




          Back edge to a                   I3=RM
              Default      I0,2
                                                            Context
                                                            Dependent
                                                            RepNodes

                                  I0=RY        I0=RY
Context-Dependent, Evolvable
Representation Selection via RIGs
   RepNode:
       A data structure governing the choice of representation for some instantiation site (or
        sites) in a program. RepNodes are grouped into “trees” with occasional back-edges to the
        root of other RepNode trees.

   A Default RepNode:
       A root of a RepNode “tree”

   RIG (Representation Instantiation Graph):
       A forest of RepNode “trees”

   Context dependence:
       The path to a particular RepNode provides a form of context. The same lexical instantiation
        site may correspond to multiple RepNodes corresponding to different dynamic instantiation
        contexts.
       The RepNode “trees” in a RIG are bounded in depth but can be arbitrarily deep (user
        control)

   Evolvability:
       RIGs can be manipulated without changing source code
       Still, manipulated RIGs always chooses representations safely
                                               MetaInstantiator
        __ci__Foo__0


    0            1           2

0   1    2   0       1   0       1   Instantiator       Rep__Foo__K

						
Related docs
Other docs by shuifanglj
Chris_Couch_2007
Views: 2  |  Downloads: 0
General Engineering Technolgy
Views: 0  |  Downloads: 0
N5200 UPS Support List
Views: 311  |  Downloads: 0
CaseStudy_Cover2go
Views: 1  |  Downloads: 0
flowers_21sep
Views: 258  |  Downloads: 0
CinahlPPT
Views: 1  |  Downloads: 0
Branson
Views: 273  |  Downloads: 0
Enterprise Engineering
Views: 194  |  Downloads: 0