Category-Based Composition in Object-Oriented Languages

Category-Based Composition in Object-Oriented Languages

Category-Based Composition in Object-Oriented Languages Paulo Jorge Lopes de Moura Department of Informatics University of Beira Interior 6201-001 Covilhã, Portugal Phone: +351 275319700, Fax: +351 275319732 [email protected] Abstract. In pure object-oriented languages like Smalltalk or Java, sharing a method between a set of unrelated objects requires the use of either inheritance or composition mechanisms. These two solutions can be problematic and cumbersome. Using inheritance, shared methods must be stored in a common ancestor, implying the use of multi-inheritance or, in single-inheritance systems, root objects with large collections of methods and complex interfaces. The use of instance variables to implement composition implies a level of indirection with the consequent need of glue code whenever we need to add the composed object methods to the container’s interface. Logtalk, a Prolog object- oriented extension, features categories as a new composition mechanism that solves these problems. Categories complement instance variable based composition and provide alternative solutions to multi-inheritance designs for single inheritance languages. Categories also provide several developing benefits such as incremental compilation and splitting of complex objects into more manageable and reusable components. 1 Introduction Sometimes we want to define and reuse a set of methods and variables that, even if functionally cohesive, do not fit the notion of an object and only make sense when composed with other code to construct new objects. Take for example the Smalltalk [1] dependency mechanism that enables an object to notify a set of dependent objects of the occurrence of some relevant event. We may need this mechanism for some of our objects but certainly not for all. In Smalltalk, this is an all–or–nothing preposition. For example, in VisualWorks [2, 3] the code is contained in a parcel and is an optional feature that one can load/add to the base system. The dependent methods (and associated data structures) are always added to the root class, Object, making them available for all objects. We either have dependents support for all objects or for none. In other systems where the dependency code is included by default, it is also stored in the root class Object. There are two issues here: how do we encapsulate and how do we reuse such a set of methods? We seek a solution that enables us to add the methods that we want to reuse to the interface of only those objects that will use them, and at the same level as the object’s locally defined methods. In hybrid languages like C++ [4], we can always write generic code like utility functions without encapsulating them inside objects. However, in pure object-oriented languages like Smalltalk or Java [5], all the code that we write must be encapsulated in some object. Sharing a method among a set of unrelated objects requires then the use of either inheritance or composition mechanisms. 1.1 Reuse via Inheritance Using inheritance, shared methods must be stored in a common ancestor. If the chosen language supports multi-inheritance, we can encapsulate our methods in a parent class for of all the objects that need to inherit such methods. Implementation multi-inheritance usually causes no problem for independent sets of cohesive methods and variables. However, languages like Smalltalk only support single-inheritance1 and others like Objective-C [6, 7] or Java only supports multi-inheritance of protocols or interfaces. Without stepping into the single- versus multi-inheritance controversy [8], we need a solution that can be adopted in single-inheritance languages like Smalltalk or Java. With single-inheritance, shared methods must be added to some common ancestor object. The outcome is often root objects with large collections of methods and complex interfaces, despite the fact that most descendant objects never use most of the methods [9]. For example, the root class of VisualWorks 3.0 has 94 methods in 25 categories while Squeak 2.5 [10, 11], another Smalltalk system, has 96 methods in nine categories. The numbers for Java and Objective-C are better. In Java 1.2 [12] we have 12 methods in class Object but 35 methods in class Class (the root of the instantiation graph). In Apple’s Objective-C frameworks [13] we have 38 instance and class methods in the root class NSObject. Single-inheritance may also force hierarchy relations that do not reflect the application domain but are rather workarounds for language limitations [14], although the problem can be mitigated by multi-inheritance of interfaces or protocols. 1.2 Reuse via Instance-Based Composition Common object-oriented languages like Smalltalk, Objective-C, Java, or C++ lack native support for composition at the same level as inheritance. The customary solution to implement composition is to use an instance variable to hold a reference to an instance of the class that contains the methods we need to reuse. This implies a level of indirection when we want to add the composed object methods to the container’s interface, with the consequent need of cumbersome glue code and some performance penalties. In addition, updating the composed object will not automatically update the container object’s interface. Note that these drawbacks of what we call instance-based composition result from our need of a different kind of composition solution, not from any inherent problem of this reusing method. 1 There are however some research Smalltalk systems that support multi-inheritance. 1.3 Reuse via Category-Based Composition In this paper, we present the category concept, a new composition mechanism, as a possible solution for these problems, especially in the context of single-inheritance languages. Categories are implemented in the Logtalk 2.x system [15, 16, 17], an object-oriented extension to the programming language Prolog [18]. First, we start with a brief description of the Logtalk system. Second, we describe the category concept, its roots and its implementation in Logtalk, comparing it to related work. Third, several examples are presented. Last, we conclude by summarizing some cases where categories can be a useful tool and discuss some possible extensions of the category concept. 2 The Logtalk System Logtalk 2.x is an Open Source [19] object-oriented extension to Prolog consisting of a pre-processor and a runtime engine. The pre-processor compiles Logtalk source files to Prolog code that is then compiled by the chosen Prolog compiler. Logtalk is a neutral object-oriented language, supporting both prototypes and classes in the same application. We can have any number of object hierarchies, including reflective designs, and freely exchange messages between any kind of objects. Logtalk supports separation of interface from implementation through the definition of protocols (similar to Objective-C protocols or Java interfaces), that can be implemented by either prototypes or classes. Data hiding is ensured by the implementation of public, protected, and private inheritance along with public, protected, and private predicates. Multiple inheritance is supported for both protocol and implementation. Other major features include parametric objects; event-driven programming; instance-defined methods; dynamic binding; static and dynamic predicates; automatic generation of documentation files in XML format; and categories, the subject of this paper. Logtalk is compatible with any operating system running a Prolog compiler complying with the Prolog ISO Standard [20]. It currently includes configuration files for nineteen commercial and academic Prolog compilers. Logtalk 1.0 has released in February 17, 1995, while the first public (non-beta) 2.x version has been released in February 9, 19992. The current distribution includes a standard library, several examples, user and reference manuals, and a programming tutorial. Logtalk users are developing applications ranging from power network fault diagnosis [21] to multi-agents systems, web interfaces, expert systems, OODBMS prototypes, CAD systems, and several academic research projects on OOP [22] and knowledge representation languages [23]. Logtalk is also being used to teach object-oriented programming to 2 Although the two systems share the same name and broad concepts, they are not compatible and are designed with different sets of goals. undergraduate students. As a Prolog extension, Logtalk can be used as an interpreted, interactive, object-oriented programming language. Using Logtalk/Prolog as a research tool in object-oriented programming has several advantages but also some drawbacks. Prolog provides an excellent tool for prototyping new ideas in object-orientation, testified by the amount of research being done in object-oriented logic programming systems [24, 25]. Code can be interpreted either as procedures or as data, enabling easy meta-programming. Interactive programming environments allow quick prototyping of new ideas. However, because Prolog is a logic programming language, it also implies an additional effort when translating Logtalk concepts and ideas to the more common jargon of languages like Smalltalk, C++ or Java. Prolog programs are made of predicate directives and definitions. Predicate definitions describe what we know to be true about the application domain. Indeed, Prolog programs can be seen as executable specifications. Predicate directives describe predicate properties, determining how predicate definitions are compiled. For those not familiar with logic programming and Prolog in particular, in this paper we may equate Prolog/Logtalk predicates with C++ object members. That is, predicates can play the role of both methods and variables. Mutable state is usually represented by dynamic predicates, i.e. predicates whose definition may be changed during runtime. 2.1 Logtalk Basics One of the Logtalk main goals is to provide Prolog with predicate encapsulation capabilities. In particular, Logtalk objects must be able to supersede the current features of the current Prolog module system [26]. To ensure a smooth learning curve, Logtalk uses standard Prolog syntax with the addition of a few directives and message sending operators.

View Full Text

Details

  • File Type
    pdf
  • Upload Time
    -
  • Content Languages
    English
  • Upload User
    Anonymous/Not logged-in
  • File Pages
    31 Page
  • File Size
    -

Download

Channel Download Status
Express Download Enable

Copyright

We respect the copyrights and intellectual property rights of all users. All uploaded documents are either original works of the uploader or authorized works of the rightful owners.

  • Not to be reproduced or distributed without explicit permission.
  • Not used for commercial purposes outside of approved use cases.
  • Not used to infringe on the rights of the original creators.
  • If you believe any content infringes your copyright, please contact us immediately.

Support

For help with questions, suggestions, or problems, please contact us