Language and Compiler Support for Mixin Programming Richard Cardone Calvin Lin, Advisor Department of Computer Sciences University of Texas at Austin April 22, 2002 The Problem Large applications are difficult and expensive to build! Variation over time Variation in execution environments 4/22/02 Cardone Defense 2 Variation over Time Class Hierarchy Tangled feature code feature 1 feature 2 feature 3 feature 4 feature 5 4/22/02 Scattered feature code Scattered/Tangled code: hard to understand, maintain, and reuse Cardone Defense 3 Variation in Execution Environments Need multiple versions of an application Different users Different market segments Different computer architectures Support for multiple versions requires effective reuse 4/22/02 Cardone Defense 4 Our Solution: Java Layers (JL) Address problems of variation over time and environments Extend Java with mixins Build software from reusable components Mixins: an object-oriented reuse technology Provide novel language and compiler support for mixin programming 4/22/02 Cardone Defense 5 Presentation Overview Mixin Background Contributions Support for Mixin Programming 4/22/02 Addressing complexity Increasing expressiveness Evaluating Mixin Programming Fidget: Building flexible widgets ACE: Comparing OO frameworks Conclusion & Future Work Cardone Defense 6 Mixins as Reusable Components Mixins: types with parametrically-specified supertypes F1<Vector> F2<F1<Stack>> class F1<T> extends T {…} Vector Stack class F2<U> extends U {…} F1_Vector F1_Stack Prototypical JL Mixin Classes F2_F1_Stack Mixins increase modularity Encapsulate feature implementations Mixins support flexible composition 4/22/02 Parent/Child relationships are not hardcoded Cardone Defense 7 Mixins Increase Complexity Increased flexibility can lead to increased complexity! Can arbitrarily compose mixins Easy to make undesirable compositions Supertypes are not known at definition time Initialization is tricky Existing OO languages don’t support useful mixin idioms 4/22/02 Cardone Defense 8 Why Java Layers? Make mixins a practical way to program Start with Java Widespread use Embodies good software engineering characteristics Address complexity of mixin programming 4/22/02 Design and implement specialized mixin support Cardone Defense 9 Contributions 1. Design new language and compiler support for mixin programming Enhance effectiveness of mixins 2. Integrate mixin support into an OO language Implement Java Layers as an extension of Java 3. Demonstrate effectiveness of mixin programming using Java Layers 4/22/02 Show that mixin programming improves application development Cardone Defense 10 Overview Mixin Background Contributions Support for Mixin Programming 4/22/02 Addressing complexity Increasing expressiveness Evaluating Mixin Programming Fidget: Building flexible widgets ACE: Comparing OO frameworks Conclusion & Future Work Cardone Defense 11 Mixin Initialization Problem: Mixin initialization is tricky because superclass is not known Classes class ParentA {ParentA(){…} …} class ParentB {ParentB(String s){…} …} class M<T> extends T {M(int i){x = i;…} …} Instantiations Superclass no-argument constructor implicitly called M<ParentA> // OK M<ParentB> // ERROR! 4/22/02 Cardone Defense 12 Previous Approaches to Mixin Initialization Restrict constructor signatures Often only no-arg constructor allowed Sometimes special argument classes are used Leads to ad-hoc initialization protocols Special initialization methods Maintenance of auxiliary data structures 4/22/02 Cardone Defense 13 Constructor Propagation JL Solution: Automatically add constructor arguments Redefined Classes class ParentB {propagate ParentB(String s){…} …} class M<T> extends T {propagate M(int i){x = i;…} …} M<ParentB> ParentB M_ParentB class M_ParentB extends ParentB { M_ParentB(int i, String s) {super(s); x = i;…} …} Simple, orthogonal, no extra code to maintain Reduces the number of hand-coded constructors 4/22/02 Cardone Defense 14 Restricting Composition Problem: Mixins can be composed in arbitrary ways Common Solution: Use type parameter constraints to prohibit invalid or undesirable compositions Constrained Type Parameter Example class TaskBase implements TaskIfc {…} class TaskQueue<T implements TaskIfc> extends T {…} Instantiations TaskQueue<TaskBase> TaskQueue<Hashtable> // OK // ERROR! But What About: TaskQueue<TaskQueue<TaskBase>> 4/22/02 Cardone Defense // Type-safe, but… 15 Semantic Checking JL’s Semantic Checking goes beyond syntactic type checking Tests for the presence, absence, ordering and cardinality of mixins Tests use regular expression pattern matching and a count operator Single Use Idiom class TaskQueue<T implements TaskIfc> extends T requires unique {…} Simpler programming model than previous approach [Batory97] See thesis for details 4/22/02 Cardone Defense 16 Overview Mixin Background Contributions Support for Mixin Programming 4/22/02 Addressing complexity Increasing expressiveness Evaluating Mixin Programming Fidget: Building flexible widgets ACE: Comparing OO frameworks Conclusion & Future Work Cardone Defense 17 Referencing the Most-Derived Class Applications are built incrementally in layers using mixins Features added one-by-one Most-derived class in mixin hierarchy contains all features DNode<SNode<int>> Linked List Example class SNode<T> { T data; SNode<T> next;} SNode_int SNode_int next; class DNode<T> extends T { DNode<T> prev;} DNode_SNode_int DNode_SNode_int prev; We want next and prev to be type DNode_SNode_int 4/22/02 Cardone Defense 18 Previous Approaches Ad-hoc naming conventions Configuration repositories [Czarnecki00] Fixed leaf class name Maintain auxiliary data New type systems [Thorup97, Bruce97-98] 4/22/02 Powerful, but change Java semantics and implementation Cardone Defense 19 Implicit This Type Parameter This refers to most-derived class in mixin-generated hierarchy Implicit type parameter This is bound at instantiation-time DNode<SNode<int>> SNode<int> Linked List Example class SNode<T> { T data; This next;} SNode_int SNode_int next; next; DNode_SNode_int class DNode<T> extends T { This prev;} DNode_SNode_int DNode_SNode_int prev; Provides a static way to reference most-derived class Easy to use 4/22/02 Cardone Defense 20 Encapsulating Feature Code Class Hierarchy feature 1 Encapsulate feature code Mixin Layers are mixins with nested types [Smaragdakis98] Encapsulate application features that crosscut multiple classes Specialize multiple (nested) classes simultaneously 4/22/02 Cardone Defense 21 Defining Mixin Layers Basic widget support class BaseFidget { class Button {…} class Checkbox {…} …} Basic display support class LtWtFidget<T> extends T { class Button extends T.Button {…} class Checkbox extends T.Checkbox {…} …} Color display support class ColorFidget<T> extends T { class Button extends T.Button {…} class Checkbox extends T.Checkbox {…} …} 4/22/02 Cardone Defense 22 Composing Mixin Layers ColorFidget<LtWtFidget<BaseFidget>> BaseFidget Button CheckBox ... LtWtFidget Button CheckBox ... ColorFidget Button CheckBox ... Deep Conformance inheritance pattern for mixin layers [Smaragdakis99] Enclosing classes form a hierarchy Nested classes form hierarchies with corresponding nested classes 4/22/02 Cardone Defense 23 Alternative Implementations of Deep Conformance Constraints One size fits all Make all subtyping deeply conforming Breaks existing code Inappropriate semantics Two sizes fit all [Smaragdakis99] Types require either deeply conforming subtypes or they don’t Requires knowledge about future usage A more flexible approach 4/22/02 Specify deep conformance constraints in subtypes Cardone Defense 24 Expressing Deep Conformance in JL JL’s deeply modifier enforces deep conformance Types can require deeply conforming type parameters Types can declare themselves to be deeply conforming class ColorFidget<T extends BaseFidget deeply> extends T deeply {class Button extends T.Button {…} class Checkbox extends T.Checkbox {…} …} T conforms to BaseFidget ColorFidget conforms to its superclass First implementation of deep conformance Simple, orthogonal, static Ensures structural compatibility in mixin layer compositions 4/22/02 Cardone Defense 25 The Big Picture Java Layers = Java + Constrained Parametric Polymorphism + Constructor Propagation + Implicit This Type Parameter + Deep Conformance + Semantic Checking Design only + Class Hierarchy Optimization 4/22/02 Cardone Defense 26 Overview Mixin Background Contributions Support for Mixin Programming 4/22/02 Addressing complexity Increasing expressiveness Evaluating Mixin Programming Fidget: Building flexible widgets ACE: Comparing OO frameworks Conclusion & Future Work Cardone Defense 27 Evaluating Java Layers Can we encapsulate application features in mixins? If YES, then we automatically support application variation Is JL’s language support for mixin programming effective? Is mixin programming practical? 4/22/02 Do mixins improve application development? Cardone Defense 28 Device-Independent Programming Today’s computing devices are diverse Workstations, PDA’s, cell phones, consumer appliances Different capabilities: CPU, RAM, I/O, graphics, storage, connectivity Still, different devices often support the same function 4/22/02 Ex: User interface, network protocol stack Cardone Defense 29 Fidget = Flexible Widgets Problem: Same function is re-implemented for different devices Solution: Implement library code that’s reusable on dissimilar devices Re-engineer a subset of Java AWT widget library using mixin layers Generate specialized GUI libraries for different devices Workstations, PDAs and cell phones Tailor interfaces to device capabilities Minimize unneeded code Generate GUI libraries from a single code-base 4/22/02 Cardone Defense 30 Generating Fidget Libraries Basic Fidget Class class BaseFidget { class Button {…} class Checkbox {…} …} Optional features implemented in 13 mixin layers: Color, event handling, look and feel, … GUI Library: Handles Mouse Events class Fidget extends EventMouse<LtWtFidget<BaseFidget>> {} GUI Library: Handles Mouse, Keys and Color class Fidget extends ColorFidget<EventKey<EventMouse<LtWtFidget<BaseFidget>>>> {} 4/22/02 Cardone Defense 31 Fidget Results Portable GUI libraries can be built using mixin layers Encapsulate GUI features in mixin layers Generate different GUI libraries from the same mixin code-base JL language support effective This and deeply are key to Fidget’s design Most widget constructors are automatically generated 4/22/02 Cardone Defense 32 Reuse with OO Frameworks Frameworks are current state of the art OO reuse technology Compare programming with mixins and programming with frameworks Frameworks are application starter kits 4/22/02 Abstract classes provide partially implemented applications Programmers supply concrete classes to complete applications Cardone Defense 33 The ACE Framework Schmidt’s Adaptive Communication Environment (ACE) C++ client/server application framework Proven, mature OO framework technology 4/22/02 More than 60 commercial and academic applications Cardone Defense 34 Re-Engineering ACE Re-engineer a subset of the ACE framework using mixins Decompose ACE interfaces into smaller JL interfaces JL interfaces define fine-grain application features Each feature is implemented in a mixin Compose applications by mixing and matching features 4/22/02 Cardone Defense 35 Re-Engineered Interfaces Task Timer Queue Reactor 1 1 1 1 1 1 ACE Interface Width 15 20 24 66 5 5 No. of JL Interfaces 10 13 13 27 3 4 Avg. JL Interface Width 1.5 1.5 1.8 2.4 1.7 1.3 No. of ACE Interfaces 4/22/02 Cardone Defense Acceptor Connector 36 ACE Results JL advantages over frameworks: Avoids complex interfaces Avoids overfeaturing Allows precise customization of applications Avoids Framework Evolution problem 4/22/02 Promotes smaller, faster executables Separately evolving framework and application code Cardone Defense 37 Related Work CLOS mixin classes use multiple inheritance [Moon, 1986; Keene, 1989] Mixins defined as abstract subclasses [Bracha & Cook, 1990] Useful in single inheritance languages Mixins are reusable software components [VanHilst & Notkin, 1996] Mixin Layers simplify mixin composition [Smaragdakis & Batory, 1998] 4/22/02 Encapsulate features that crosscut multiple classes Cardone Defense 38 Conclusion Designed/Implemented novel support for mixin programming [Cardone & Lin, ICSE 2001], [Cardone, Brown, McDirmid & Lin, AOSD 2002] Integrated mixin support into a conventional OO language Implementation lessons described in thesis Demonstrated benefits of mixin programming over current techniques [Batory, Cardone & Smaragdakis, SPLC 2000] Specialized language and compiler support make mixins a practical reuse technology 4/22/02 Cardone Defense 39 Future Work Build real-world applications using mixins Implement a JL-to-bytecode compiler Implement Semantic Checking and Class Hierarchy Optimization Explore different Java bytecode representations for mixins Explore generative programming 4/22/02 What compile-time code transformations should be supported? Cardone Defense 40 The End www.cs.utexas.edu/users/richcar/JavaLayers.html 4/22/02 Cardone Defense 41 Semantic Checking Undesirable compositions are often type-safe Ex: TaskQueue<TaskQueue<TaskBase>> JL’s Semantic Checking goes beyond syntactic type checking Classes define semantic attributes Each class hierarchy constructs an ordered attribute list Classes test attribute lists Tests use regular expressions and a count operator Attributes are tested for presence, absence, ordering and cardinality Test failure aborts compilation 4/22/02 Cardone Defense 42 Semantic Checking Contributions JL’s Semantic Checking is: Simple Static Orthogonal Expressive (so far) [Batory97] Designed, but not implemented 4/22/02 Cardone Defense 43 Runtime Efficiency Fact: Mixins generate deep hierarchies of small classes Question: How does this affect performance? TCP Network Protocol Stack send(){…} Secure send(){…; super.send();} Compress send(){…; super.send();} LogError send(){…; super.send();} KeepAlive send(){…; super.send();} KeepAlive<LogError<Compress<Secure<TCP>>>> 4/22/02 Cardone Defense 44 Class Hierarchy Optimization Class Hierarchy Optimization Flatten hierarchies, but preserve leaf class interface Inline methods Simple idea, not so simple to do Nested types Access control Contributions Novel optimization Novel design (not implemented) 4/22/02 Cardone Defense 45 An Interesting Design Topic Basic Fidget Class class BaseFidget { abstract class Component {…} class Button extends Component {…} …} Mixin Layers class LtWtFidget<T extends BaseFidget deeply> extends T deeply { abstract class Component extends T.Component {…} class Button extends T.Button {…} …} class ColorFidget<T extends BaseFidget deeply> extends T deeply { abstract class Component extends T.Component {…} class Button extends T.Button {…} …} … 11 other mixin layers 4/22/02 Cardone Defense 46 Building Fidget Libraries ColorFidget<LtWtFidget<BaseFidget>> BaseFidget LtWtFidget ColorFidget 4/22/02 Component Button ... Component Button ... Component Button ... Cardone Defense 47 The Sibling Pattern Basic Fidget Class class BaseFidget<> { abstract class Component {…} class Button extends This.Component {…} …} The Sibling design pattern A nested class (Button) inherits from the most-derived subclass of its sibling class (Component) Useful semantics for mixins In a deeply conforming mixin layer, changes to a nested class can be inherited by its sibling classes 4/22/02 Pattern also used in GenVoca [Batory98] and Jiazzi [McDirmid01] Cardone Defense 48 Key Insights Mixins use feature-specific interfaces to enhance usability Applications support only the interfaces/code they need Mixins defer parent/child relationships to enhance flexibility 4/22/02 Could use mixins to build frameworks! Cardone Defense 49 Fidget Design Applications User Kernel Fidget Code HAL Graphic System 4/22/02 Cardone Defense 50