Late-bound Pragmatical Class Methods

Similar documents
Weiss Chapter 1 terminology (parenthesized numbers are page numbers)

Object Oriented Programming. Java-Lecture 11 Polymorphism

M301: Software Systems & their Development. Unit 4: Inheritance, Composition and Polymorphism

Agenda. Objects and classes Encapsulation and information hiding Documentation Packages

Chapter 11. Categories of languages that support OOP: 1. OOP support is added to an existing language

The Java Programming Language

PROGRAMMING LANGUAGE 2

Call by Declaration. Erik Ernst 1. Dept. of Computer Science, University of Aarhus, Denmark

COP 3330 Final Exam Review

Implementing Object Equivalence in Java Using the Template Method Design Pattern

What is Inheritance?

More About Objects. Zheng-Liang Lu Java Programming 255 / 282

Java: introduction to object-oriented features

What s Conformance? Conformance. Conformance and Class Invariants Question: Conformance and Overriding

Subtyping. Lecture 13 CS 565 3/27/06

Inheritance (Chapter 7)

Comp 311 Principles of Programming Languages Lecture 21 Semantics of OO Languages. Corky Cartwright Mathias Ricken October 20, 2010

Lecture 13: Object orientation. Object oriented programming. Introduction. Object oriented programming. OO and ADT:s. Introduction

A Short Summary of Javali

CS558 Programming Languages Winter 2013 Lecture 8

Lecture Notes on Programming Languages

Data Abstraction. Hwansoo Han

Design issues for objectoriented. languages. Objects-only "pure" language vs mixed. Are subclasses subtypes of the superclass?

CS-XXX: Graduate Programming Languages. Lecture 22 Class-Based Object-Oriented Programming. Dan Grossman 2012

Object-Oriented Programming

HAS-A Relationship. Association is a relationship where all objects have their own lifecycle and there is no owner.

Object Oriented Programming is a programming method that combines: Advantage of Object Oriented Programming

Chapter 4 Defining Classes I

What are the characteristics of Object Oriented programming language?

CPS 506 Comparative Programming Languages. Programming Language

Data Structures (list, dictionary, tuples, sets, strings)

CS153: Compilers Lecture 11: Compiling Objects

CS-202 Introduction to Object Oriented Programming

Inheritance. Unit 8. Summary. 8.1 Inheritance. 8.2 Inheritance: example. Inheritance Overriding of methods and polymorphism The class Object

Today s lecture. CS 314 fall 01 C++ 1, page 1

Overview of OOP. Dr. Zhang COSC 1436 Summer, /18/2017

Class, Variable, Constructor, Object, Method Questions

Graphical Interface and Application (I3305) Semester: 1 Academic Year: 2017/2018 Dr Antoun Yaacoub

Implementing Software Connectors through First-Class Methods

Practice for Chapter 11

Day 4. COMP1006/1406 Summer M. Jason Hinek Carleton University

CS152: Programming Languages. Lecture 23 Advanced Concepts in Object-Oriented Programming. Dan Grossman Spring 2011

Chapter 5 Object-Oriented Programming

Object-oriented Programming. Object-oriented Programming

Subtyping (Dynamic Polymorphism)

CS260 Intro to Java & Android 03.Java Language Basics

OBJECT ORİENTATİON ENCAPSULATİON

Chapter 10 :: Data Abstraction and Object Orientation

Atelier Java - J1. Marwan Burelle. EPITA Première Année Cycle Ingénieur.

CS558 Programming Languages

BBM 102 Introduction to Programming II Spring Inheritance

Java Fundamentals (II)

Conformance. Object-Oriented Programming Spring 2015

CS-XXX: Graduate Programming Languages. Lecture 23 Types for OOP; Static Overloading and Multimethods. Dan Grossman 2012

C++ Programming: Polymorphism

Idioms for Building Software Frameworks in AspectJ

Computer Science 225 Advanced Programming Siena College Spring Topic Notes: Inheritance

Grade Weights. Language Design and Overview of COOL. CS143 Lecture 2. Programming Language Economics 101. Lecture Outline

Universe Type System for Eiffel. Annetta Schaad

Field Analysis. Last time Exploit encapsulation to improve memory system performance

Object typing and subtypes

Concepts of Programming Languages

Software Paradigms (Lesson 3) Object-Oriented Paradigm (2)

Comp 248 Introduction to Programming Chapter 4 & 5 Defining Classes Part B

Contents. I. Classes, Superclasses, and Subclasses. Topic 04 - Inheritance

Chapter 9 :: Data Abstraction and Object Orientation

Introduction to Programming Using Java (98-388)

Chapter 5: Procedural abstraction. Function procedures. Function procedures. Proper procedures and function procedures

Outline. Java Models for variables Types and type checking, type safety Interpretation vs. compilation. Reasoning about code. CSCI 2600 Spring

4 CoffeeStrainer Virtues and Limitations

Java Design Goals. Lecture 32: Java. Java Original implementations slow! Exceptions & Subtyping. - void method readfiles() throws IOException {...}!

Review: Object Diagrams for Inheritance. Type Conformance. Inheritance Structures. Car. Vehicle. Truck. Vehicle. conforms to Object

Inheritance -- Introduction

CSE 401/M501 Compilers

Classes and Methods עזאם מרעי המחלקה למדעי המחשב אוניברסיטת בן-גוריון מבוסס על השקפים של אותו קורס שניתן בשנים הקודמות

OBJECT ORIENTED PROGRAMMING USING C++ CSCI Object Oriented Analysis and Design By Manali Torpe

Implements vs. Extends When Defining a Class

Java Magistère BFA

Classes and Methods לאוניד ברנבוים המחלקה למדעי המחשב אוניברסיטת בן-גוריון

CMSC131. Inheritance. Object. When we talked about Object, I mentioned that all Java classes are "built" on top of that.

OO Technology: Properties and Limitations for Component-Based Design

An Introduction to Subtyping

Compilation of Object Oriented Languages Tik Compilers Seminar

Lecture 36: Cloning. Last time: Today: 1. Object 2. Polymorphism and abstract methods 3. Upcasting / downcasting

Example: Count of Points

Support for Subtyping and Code Re-use in Timor

Oops known as object-oriented programming language system is the main feature of C# which further support the major features of oops including:

JOURNAL OF OBJECT TECHNOLOGY

Object Model. Object Oriented Programming Spring 2015

First IS-A Relationship: Inheritance

Java. Classes 3/3/2014. Summary: Chapters 1 to 10. Java (2)

Week 7. Statically-typed OO languages: C++ Closer look at subtyping

JAVA: A Primer. By: Amrita Rajagopal

CSE 307: Principles of Programming Languages

Jam: A Smooth Extension With Java Mixins

Technical Report. Computer Science Department. Operating Systems IMMD IV. Friedrich-Alexander-University Erlangen-Nürnberg, Germany

Fortgeschrittene objektorientierte Programmierung (Advanced Object-Oriented Programming)

Lecture 23: Object Lifetime and Garbage Collection

The Java Type System (continued)

More Relationships Between Classes

Transcription:

Late-bound Pragmatical Class Methods AXEL SCHMOLITZKY, MARK EVERED, J. LESLIE KEEDY, GISELA MENGER Department of Computer Structures University of Ulm 89069 Ulm, Germany {axel, markev, keedy, gisela@informatik.uni-ulm.de Abstract Binary methods are one of the challenges for designers of object-oriented programming languages. In this paper we discuss binary class methods (class methods that receive parameters of their own class type) as an alternative for typical uses of binary instances methods and show that they are often less troublesome, more symmetrical and more expressive. However, the main drawback of class methods as they are defined in languages like C++ and Java is that their static binding excludes them from being used in certain codereuse scenarios that need late-bound selfreference. We propose a small and surprisingly simple language mechanism to overcome this drawback. This mechanism can easily be adopted by languages that offer statically bound class methods. We further give the semantics of this extension as a mapping onto an object model without class methods. 1 Introduction A binary method, as defined in [Bru95], is an instance method of some object of type τ that has a parameter of the same type τ. Binary methods are (still) one of the challenges for designers of object-oriented programming languages as is well discussed in that paper. They can be seen as a focus demonstrating the difficulty of combining three partly competing goals of modern objectoriented languages: static type safety encapsulation flexibility in code reuse In this paper we discuss binary pragmatical class methods as an alternative for typical uses of binary methods (which will be referred to as binary instance methods for better distinction). In analogy to the definition of a binary instance method we define a binary class method as a class method of some class defining type τ that has at least one parameter of this type τ. As with binary instance methods, this definition does not exclude further parameters, and the typical case of a binary class method is indeed a method with two parameters of type τ. We first show that binary pragmatical class methods are often more appropriate and less troublesome than binary instance methods. We

further show that one of the defining qualities of pragmatical class methods their static binding is a logical property that is useful for extending their expressability but that need not imply that they have to be statically bound in their implementation. Throughout the paper we use the Java Programming Language [GJS96] as the language for demonstration, but the results in this paper apply equally to other object-oriented languages. Before we can start the discussion we must define the term pragmatical class method. 2 Pragmatical class methods It may seem obvious what is meant by a class method but if we take a closer look we must differentiate several distinct properties. What are the defining properties of a class method? First of all class methods clearly appear only in languages that directly support a notion of a class. Thus we can narrow the discussion to class-based languages like Smalltalk [GoR89], C++ [ElS90], Eiffel [Mey92], and Java. The exact status of a class differs between these languages, however. In Smalltalk classes are instances of meta classes and thus are not special in respect to their methods; class methods are simply instance methods of a meta class instance. In Eiffel classes are only a compile-time notion that completely disappears at run-time; thus class methods simply do not exist in the language model. In C++ and Java a compromise is made; there exists a notion of a class object that can be manipulated at runtime, but this object is statically defined. Thus class methods can be statically bound in these languages. The language models of Smalltalk and Eiffel can be seen as more consistent either fully accept classes as objects, treat them as first-class citizens and naturally support class methods, or fully neglect classes at run-time and by this keep the principle that every invocation at run-time is an invocation of a first-class object. In the following we refer to the pragmatical view of class methods in C++ and Java by calling them pragmatical class methods. Although such pragmatical class method do not neatly fit into regular object models they are well accepted in practice as is shown by the decision of the designers of Java to adopt the concept from C++. What then are the defining properties of a pragmatical class method? We formulate them as follows: Class Bound: A pragmatical class method belongs to a class and is part of the class definition. This implies for example that a class method is inherited if the class it belongs to is inherited. Full Access: Pragmatical class method have access to the private fields and methods of the class. This can be concluded from the Class Bound property and is especially relevant for the efficient implementation of binary operations. Static Binding: A pragmatical class method is statically bound. This means that the language entity a class method invocation is qualified with is assumed to be a static reference. No Self: Inside the body of a pragmatical class method no reference to 'self' is allowed. 2

Only the last two properties distinguish a pragmatical class method from an instance method. The aim of this paper is to show that the Static Binding property can partly be relaxed to make pragmatical class methods even more valuable than they already are. Before we discuss this point, however, we first demonstrate the value of binary pragmatical class methods in comparison to binary instance methods. In the following we refer to pragmatical class methods simply with the term class method. 3 Binary class methods versus binary instance methods In this section we discuss binary class methods as an alternative to binary instance methods. We compare them by using both kinds of methods to model binary operations. A binary operation shall be understood as an abstract operation on an abstract object type that involves two instances of that type. For example, the abstract binary operation comparison for equality on objects of a type T can be modeled either as the binary instance method boolean equals(t other) of a class T 1 or as the binary class method boolean equal(t o1, T o2) of a class T 2, with both T 1 and T 2 implementing T. We compare three possibilities for modeling a binary operation that tests two instances for equality. These instances are either instances of a Point class or of a ColorPoint class. Instances of the Point class represent two-dimensional cartesian points. Instances of the ColorPoint class represent colored points, i.e. two-dimensional cartesian points with an additional color property. Equality for points shall be defined as equality of the coordinates, whereas equality for colored points shall be defined as equality of the coordinates and equality of the color property. In our scenario we are particularly interested in the possibility of comparing colored points just for point equality. Similar practical programming examples are comparing two lists for equality as bags (i.e. without respect to their ordering) and comparing two employee objects for equality as persons (i.e. is it the same person employed in two different ways), In all of the following Java modelings the representation of an object of class Point is encapsulated by access methods to its logical components, namely its x- and y-coordinate. These are modeled as private instance fields called rep_x and rep_y, respectively. The class ColorPoint additionally defines access methods to a private color field called rep_color. Class Point defines a constructor with two parameters, giving initial values for the coordinates. Class ColorPoint defines a constructor with three parameters, giving initial values for the coordinates and the color. All parameters are of type int for simplicity. Modeling 1: instance methods with overriding In the first modeling the equality operation for two points is implemented in the Java-conformant style by overriding the binary instance method equals of class Object. Class ColorPoint inherits from Point and again overrides method equals with an implementation that compares two instances of ColorPoint. 3

class Point { // modeling 1 public boolean equals (Object other) { if (other instanceof Point) { Point p = (Point)other; return (this.rep_x == p.rep_x) && (this.rep_y == p.rep_y); else return false; class ColorPoint extends Point { public boolean equals (Object other) { if (other instanceof ColorPoint) { ColorPoint c = (ColorPoint)other; return (super.equals(other)) && (this.rep_color == c.rep_color); else return false; This is the approach encouraged by the Java style but it has two drawbacks. The first (minor) is efficiency: The instanceof test and the cast both incur run-time checks, which are necessary because the parameter has a generic type. The second drawback is more problematic. It is not possible to compare two ColorPoint instances only for the equality of their coordinates, i.e. use the code of the equals method in Point for the comparison. This problem can be solved if we define binary instance methods with overloading instead of overriding. Modeling 2: instance methods with overloading In the second modeling the test for equality in class Point is implemented as a real binary instance method, i.e. an instance method that is passed a parameter of type Point. class Point { // modeling 2.1 public boolean equals (Point other) { return (this.rep_x == other.rep_x) && (this.rep_y == other.rep_y); The implementation for equals (method 1 in the following) can in this case be sure that it is passed a Point instance and can directly manipulate the internal representation. No runtime checks are needed. Class ColorPoint inherits from this version of Point and provides its own binary instance method (method 2) for testing the equality of colored points. class ColorPoint extends Point { // 2.2 public boolean equals (ColorPoint other) { return (super.equals(other)) && (this.rep_color == other.rep_color); With this modeling equals is statically overloaded in ColorPoint and thus ColorPoint has two equals methods 1. Method 1 is inherited from Point and has a formal parameter of type Point. Method 2 is provided directly with a formal parameter of type ColorPoint and thus can access the internal color field of its argument unconditionally. Again no runtime overhead is incurred. If we now assume the declarations Point p1 = new Point(1,1); Point p2 = new Point(0,0); ColorPoint c1 = new ColorPoint(1,1,1); ColorPoint c2 = new ColorPoint(1,1,0); then the following expressions will behave like this: p1.equals(p2) // method 1 false p1.equals(c1) // method 1 true c1.equals(p1) // inherited method 1 true c1.equals(c2) // method 2 false 1 In fact, in Java it has three equals methods, but in this discussion we can ignore the one from class Object. 4

Note that in none of these cases the dynamic type of the called object influences the semantics of the call, because no method is overridden. With this modeling it is possible to test whether two ColorPoint instances only have the same coordinates. This can be done by forcing the compiler to statically choose the first equals method. One way is to pass an argument of static type Point. // passing a ColorPoint as a Point c1.equals((point)c2) // inherited method 1 // true In this case the compiler has the choice between two methods, because the interface of ColorPoint offers two equals signatures. But only one of these allows an argument of static type Point and is thus chosen. Again the dynamic dispatch at runtime just causes the inherited code of method 1 to be called. Another way to achieve the same is to make the call to c1 via a variable of type Point. // calling a ColorPoint as a Point ((Point)c1).equals(c2) // method 1 true Here the fact is used that a call of the equals method of a variable of type Point is statically determined to mean the only equals signature Point offers, namely the one that expects an argument of type Point. The subtyping rules allow us to pass a variable of type ColorPoint. The dynamic dispatch at runtime then just causes the inherited code of method 1 to be called. Both solutions are rather cumbersome and detract from the readability of the source. One might prefer to have a way of directly saying "now call the Point equals method for these two ColorPoint variables". Modeling 3: class methods with overloading This can be achieved by modeling the comparison operations with binary class methods (which we name equal instead of equals). class Point { // modeling 3 (Point p1, Point p2) { return (p1.rep_x == p2.rep_x) && (p1.rep_y == p2.rep_y); class ColorPoint extends Point { (ColorPoint p1, ColorPoint p2) { return (Point.equal(p1,p2)) && (p1.rep_color == p2.rep_color); With this modeling it is straightforward to compare two ColorPoint variables for the equality of their coordinates: Point.equal(c1,c2) The other expressions from above are also more readable with binary class methods: Point.equal(p1,p2) Point.equal(p1,c1) Point.equal(c1,p1) ColorPoint.equal(c1,c2) Overall this modeling better reflects the fact that the two equal methods are semantically different operations. However, this modeling has a minor drawback. Class ColorPoint has two equal methods in its interface, one inherited with Point parameters, the other directly provided with ColorPoint parameters. The former is even less useful than the inherited equals method in modeling 2, which at least made it possible to pass a Point 5

variable to an equals method of a ColorPoint variable. We come back to this in section 4. Other arguments for class methods A further advantage of binary class methods (or class methods in general) is that they can better handle exceptional cases. If in an invocation of a binary instance method the receiver is a null reference the call will fail, although the comparison with a null reference could be welldefined in an application. Binary class methods are in general preferable to binary instance methods for symmetrical operations like the comparison for equality, where two or more objects of the same type are treated 'on equal terms'. These seem to constitute most applications of binary instance methods in practice. To model such operations with binary instance methods is an asymmetrical preference of one argument that is hard to justify. 4 Pragmatical class methods allow covariance We have defined that pragmatical class methods are statically bound. Although this property can restrict flexibility (see next section) it can also be seen as an advantage. We demonstrate this by informally introducing a language extension. We motivate this extension by recalling the drawback from modeling 3, the useless equal method in ColorPoint. This unnecessary duplication could be avoided by the use of the type identifier ThisType for typing the parameters of equal, which would imply a covariant adaptation of the parameter types. Informally, for type checking ThisType automatically adapts to the type of the class it is defined in. Such constructs have been extensively discussed for instance methods but not for class methods. Modeling 4: class methods with ThisType and hiding By typing the parameters of class method equal with ThisType we get the following: class Point { // modeling 4 return (p1.rep_x == p2.rep_x) && (p1.rep_y == p2.rep_y); class ColorPoint extends Point { (ThisType p1,thistype p2) { return (Point.equal(p1,p2)) && (p1.rep_color == p2.rep_color); We define this modeling to mean that the equal method in ColorPoint hides the equal method from Point (as it is defined for class methods with identical signatures in Java). The effect then would be that both Point and ColorPoint offer just one equal method in their interface. The interesting point is that such a covariant adaptation does not result in the well known subtyping problems with binary instance methods. This is due to the fact that class methods are not dynamically dispatched (Static Binding property). It follows that ColorPoint can still be seen as a subtype of Point and we can still compare ColorPoint instances for Point equality in a straightforward way. It is well known that the introduction of a flexible type identifier like ThisType is not as easy as it 6

may seem here. In order to avoid recompilation or repeated type checking on code-reuse, certain restrictions must be placed on code that contains ThisType (for example no assignment of a Point expression to a ThisType variable). Such restrictions are discussed for example for matching [BSG95]. What about matching anyway? At this point it is interesting to see how matching is related to this discussion. Matching is a relation between classes very similar to the subtype relation but allowing covariant parameter type changes in instance methods via ThisType. If we again assume that Java were extended by ThisType, the Point/ColorPoint example could look like this: class Point { public boolean equals (ThisType other) { return (this.rep_x == other.rep_x) && (this.rep_y == other.rep_y); class ColorPoint extends Point { public boolean equals (ThisType other) { return (super.equals(other)) && (this.rep_color == other.rep_color); With this modeling equals in ColorPoint overrides the inherited method, as in modeling 1. But matching is a generalization of subtyping, and especially in this case the covariant change of parameter type excludes subtyping. But if ColorPoint is not a subtype of Point it is not possible to pass a ColorPoint object to a method that expects a Point parameter. This means that matching doesn't help with the situation we want to express, to call the Point equals methods for two ColorPoint variables. 5 Dependencies between class methods Given that binary class methods are often more readable and more expressive than binary instance methods in subtype relationships, we now turn to the question of code-reuse. As we will see, the Static Binding property which allows statically type-safe covariant parameters can lead to inflexibility in code-reuse. Sometimes operations are defined in terms of other operations. Assume the simple case that the binary operation equalandvisible for two points is defined as returning true if the equal operation returns true and both points are visible (an additional attribute), and otherwise returning false. This could be modeled with binary class methods as follows: class Point { AndVisible if (equal(p1,p2)) { In this example the class method invocation of equal in equalandvisible is not qualified which means that it is implicitly qualified with the class name it is defined in: if (Point.equal(p1,p2)) { For colored points the operation equalandvisible could also be defined on the basis of equal, but here on the basis of equal for colored points. If we model this with a class inheriting from Point and hiding equal: 7

class ColorPoint extends Point { // new implementation of equal Then the fact that pragmatical class methods are statically bound implies that in the inherited code of equalandvisible the equal method from Point is still called. The only way to work around this would be to reimplement equalandvisible as well. It would be nice if it were possible to define the equalandvisible method on the basis of the equal method in the current class. If both binary operations were modeled with binary instance methods this relationship would be defined implicitly. A language extension An appropriate language mechanism to express such a relation also between class methods could look like this: class Point { AndVisible if (ThisType.equal(p1,p2)) { The informal semantics of this mechanism is that the class method of the current class is called. If this mechanism were provided in a language like Java, class methods would gain a great deal of flexibility with respect to code-reuse. In combination with covariance many typical binary operations could be modeled very elegantly with pragmatical class methods. For Java, for example, a binary covariant class method equal with two parameters of type ThisType could be defined in class Object. Just like the binary instance method equals it could by default be implemented as a test for reference equality, but be hidden in subclasses that want to define equality differently. The advantage would be that its parameter typing would adapt to the type of the inheriting class. 6 Semantics of late-bound pragmatical class methods It is obvious that pragmatical class methods can not be statically bound if the mechanism of the last section is provided. We thus have to claim pragmatical class methods to be late-bound. On the other hand we don t want to lose the defining property of pragmatical class methods their Static Binding because it is the precondition that pragmatical class methods can allow covariance of their argument types. In this section we define a semantics of late-bound pragmatical class methods that integrates both requirements. Mapping to instance methods We define the semantics of a class method invocation as a mapping onto an instance method invocation. This mapping is straightforward for any object-oriented language and thus allows us to integrate pragmatical class methods even into languages that do not offer class methods at all (like Eiffel). A prerequisite is that class method declarations are mapped onto instance method declarations. 8

Mapping declarations DeclMap: For any class method cm the class declaration class C { static <return type> cm ( <args> ) { <statements> is mapped onto class C { <return type> cm ( <args> ) { <statements> The mappings of class method invocations are equally simple. Mapping invocations Three cases have to be considered: class method invocations qualified with a class name, class method invocations qualified with ThisType and unqualified class method invocations. InvocMap1: For any class C declaring class method cm a class method invocation of the form C.cm( <args> ); is mapped onto (new C()).cm(<args>); InvocMap2: Any class method invocation of a class method cm of the form ThisType.cm(<args>); is mapped onto cm(<args>); InvocMap3: For any class C declaring class method cm a class method invocation of the form cm(<args>); is mapped onto (new C()).cm (<args>); Comments The class method invocations in InvocMap2 and InvocMap3 can only appear inside a class C declaring cm. InvocMap2 implies that an invocation via ThisType is mapped onto an invocation via this, which will always be valid. Either the invocation appears in an instance method of C and this must have a defined value; or the invocation appears in a class method that, due to DeclMap, is mapped onto an instance method. InvocMap3 means that an unqualified class method invocation is assumed to be equivalent to a class method invocation that is explicitly qualified with a class name. This reflects the interpretation of unqualified class method invocations in Java. Alternatively, unqualified invocations could be mapped like class method invocations that are explicitly qualified with ThisType. This would more consistently mirror the interpretation of unqualified instance method invocations. With our definition we preferred compatibility over consistency. Realization The semantics we have defined are straightforward and could be directly implemented. In the code resulting from InvocMap1 and InvocMap3 the newly created instance is just a dummy instance. Because instance creation is typically expensive and might be more complicated (for example because of constructor parameters) this dummy instance should preferably be created at system startup and provided with each call. Note that this dummy 9

instance can be seen as an instance representing the class object. We regard the extra indirection required for a late-bound call in comparison to a staticallybound call as being insignificant in the overall cost of invoking a method. Pragmatical class methods refined In view of these semantics, we must refine the third of the defining properties of pragmatical class methods from section 2 (changes are given in italics): Static Binding: A pragmatical class method is logically statically bound for clients of a class. This means that for a client the language entity a class method invocation is qualified with is assumed to be a logically static reference. From a clients point of view a pragmatical class method is a method that is statically bound. Thus a client knows exactly which code is being invoked the code of the class the class method is invoked on. Although this is what a programmer sometimes wants, it need not mean that pragmatical class methods must be statically bound in their implementation. 7 Summary In this paper we have discussed pragmatical class methods as a useful concept in object-oriented programming languages. First we have shown that in some situations binary class methods have advantages over binary instance methods in terms of readability, expressability and symmetry. In particular, pragmatical binary class methods allow covariant parameter type adaptation without paying the price of losing the subtype relation between classes, as is the case with binary instance methods and matching. As the main contribution we have shown that a simple language extension can eliminate the inflexibility of pragmatical class methods for code-reuse. We defined the semantics of this extension with a simple mapping onto a language model that need only provide instance methods. Our extension and its semantics are so simple that the extension could easily be integrated into existing languages. Besides a minor loss in efficiency we can see no reason why pragmatical class methods in future languages should not be defined in this way. References [Bru95] Bruce, K. B., et al.: On Binary Methods, Theory and Practice of Object Systems, 1:3, S. 221-242, 1995. [BSG95] Bruce, K. B., Schuett, A., Gent, R. v.: PolyTOIL: A Type-Safe Polymorphic Object- Oriented Language, Proc. ECOOP '95, Aarhus, Denmark; in Lecture Notes in Computer Science 952, Springer-Verlag, 1995. [ElS90] Ellis, M. A., Stroustrup, B.: The Annotated C++ Reference Manual, Addison- Wesley, Reading, MA, 1990. [GoR89] Goldberg, A., Robson, D.: Smalltalk-80: The Language, Addison-Wesley, Reading, MA, 1989. [GJS96] Gosling, J., Joy, B., Steele, G.: The Java Language Specification, Addison-Wesley, Reading, MA, 1996. [Mey92] Meyer, B.: Eiffel: the Language, Prentice-Hall, New York, 1992. 10