Inheritance is Specialisation Position paper for the Inheritance workshop of ECOOP ’ 02

How can we get a simpler but much more general subclass construct? This position paper takes a “specialisationist” approach to inheritance. Old SIMULA virtues are restored to prominence, but boiled with new unificational ingredients to obtain a substrate of specialisation. Ever since the advent of Smalltalk there has been a strong tension in the object-oriented community between two opposing views of the role of inheritance: as an incremental modification mechanism or as a vehicle for conceptual modelling. Madsen [5] and many others characterise the two approaches as the “American” and “Scandinavian” schools, respectively. Nowadays, such a geographical terminology hardly remains valid (if ever it was), but the tension remains: should we strive for maximal flexibility of inheritance, to improve the possibilities for later unanticipated reuse, or should we attend above all to the conceptual integrity of the subclassing mechanism to aid the use of the programmers’ intuition in the development process. Here we shall adopt a different terminology, focusing instead of the primary role of subclassing in the two views, and thus refer tomodificationismand specialisationism: the former view would in principle endorse a description of oranges by inheritance from apples (sometimes called “sideways inheritance” because it does not obey the structure of a classification hierarchy), the latter would allow these to be related only through a common superclass. The line of argument in this position paper will be as follows: – Modificationism is loosing out. Its basic assumptions do not hold, and the main benefits of object-orientation in all levels of software development derive from the core principles of specialisationism – Therefore language designers do not have to pay special heed to modificationist needs, but can concentrate on improving inheritance as a specialisation construct – This idea is acted out in a very simple and general programming language, R UNE, which derives its simplicity from abandoning modificationist ambitions – It is concluded that you can get much nicer languages by sticking to a specialisation view of inheritance. To avoid confusion, we use the term “modify” to signify incremental modification of classes through inheritance, while “change” denotes actual changes to the source code of a class. 1 The Demise of Modificationism The golden modificationist vision of object-orientation maintained that programmers about to embark on writing a new class would save a lot of work by inheriting from existing classes sufficiently similar to what was desired. In this way, you don’t need to rewrite the base class, and you get changes and bug fixes for free. This has not happened much in practice, and for many good reasons. If the classes to reuse belong to some other project or organisation they may: – not be possible to find – not be modifiable in exactly the desired way – change unexpectedly once we start depending on them (the fragile base class problem). If the class to reuse is developed in the same project there is usually no good reason not to change it: better for the project as a whole to factor out a common superclass: you get a better overall class structure, and avoid unnecessary interdependencies of the code. Thus, in practice there is little use for modificationist inheritance in modern object-oriented software development. 2 The Benefits of Specialisationism The specialisationism view has proven its beneficial effect on software development in a number of ways. 2.1 Conceptual clarity The classical argument for specialisationism (see e.g., [8]) is conceptual: Classes represent concepts, and subclassing represents conceptual specialisation. Thus, “Apple” specialises “Fruit”, because any apple is a fruit, and has all the properties required to be worthy of the term “Fruit”. Insistence on this intimate relationship of programming and classification opens up the door to the programmers’ intuition and aids them greatly in the design and structuring of programs. In the words of Kristen Nygaard, “to program is to understand”. In typed object-oriented programming languages, this realisation is reflected in the type system as subtyping: classes represent types, and subclasses are subtypes. Thus, inheritance is constrained by the commitment of subclasses not to contradict their superclasses. Even in untyped systems, however, a conceptual approach to subclassing has the desirable effect that you get to depend only on changes that really should affect you. The concept of “apple” should be affected by changes to “fruit”, but not to “orange”. 2.2 Designing for change Closely related to the conceptual view, although using quite a different terminology, is the design philosophy embodied in the notion of design patterns , and very well described in the “GoF” book [3]. Here the focus is on black-box over white-box reuse: composition is a much better vehicle for reuse that inheritance, because it minimises the dependencies between classes, making them more robust towards changes in other code. In the GoF book, subclassing is used for polymorphism: Abstract superclasses describe the commonalities among different related concrete classes, freeing clients from dependencies on particular implementation details that are none of their business. Frameworks build on a similar philosophy, providing large amounts of concrete functionality operating on abstract classes. Concrete subclasses of these are provided by the individual framework user, so independence of their implementation details is essential.