Genericity Vs Inheritance
Total Page:16
File Type:pdf, Size:1020Kb
s Genericity Versus Inheritance Bertrand Meyer Interactive Software Engineering, Inc., 270 Storke Road, Suite #7, Goleta CA 93117 ABSTRACT with which a software system may be changed to account for modifications of its requirements), reus Genericity, as in Ada or ML, and inheritance, as in ability (the ability of a system to be reused, in whole object-oriented languages, are two alternative tech or in parts, for the construction of new systems), and niques for ensuring better extendibility, reusability, compatibility (the ease of combining a system with and compatibility of software components. This ar others). ticle is a comparative analysis of these two methods. Good answers to these issues are not purely It studies their similarities and differences and as technical, but must include economical and mana sesses to what extent each may be simulated in a gerial components as well; and their technical as language offering only the other. It shows what fea pects extend beyond programming language fea tures are needed to successfully combine the two ap tures' to such obviously relevant concerns as proaches in an object-oriented language that also fea specification and design techniques. It would be wrong, tures strong type checking. The discussion introduces however, to underestimate the technical aspects and, the principal aspects of the language EiffePM whose among these, the role played by proper programming design, resulting in part from this study, includes language features: any acceptable solution must in multiple inheritance and a limited form of genericity the end be expressible in terms of programs, and under full static typing. programming languages fundamentally shape the software designers' way of thinking. This article is a comparative analysis of two OVERVIEW classes of programming language features for en hancing extendibility, reusability, and compatibil Despite its name, today's software is usually ity. It assesses their respective strengths and weak not soft enough: adapting it to new uses turns out nesses, examines which of their components are in most cases to be a harder endeavor than should equivalent and which are truly different, shows how be. It is thus essential to find ways of enhancing such the two approaches complement each other, and ex software quality factors as extendibility (the ease plains how they have been combined in a particular programming language design. The two approaches studied are genericity and inheritance; both address the above issues by allow This article is a revised version of a paper presented at OOPSLA (First ACM Symposium on Object-Oriented Program ing the definition of flexible software elements ame ming Systems, Languages and Applications, Portland, Oregon, nable to extension, reuse, and combination. The first Sept. 29-0ct. 2, 1986), Ed. Norman Meyrowitz, published as Sig is a technique for defining elements that have more plan Notices, 21, 11, pp. 391-405. Trademarks: Unix (AT&T); Ada (U.s. DoD); Eiffel (Inter than one interpretation, depending on parameters active Software Engineering). representing types; the second makes it possible to Journal of Pascal, Ada, & Modula-2, Vol. 7, No.2, pp. 13-30 (1988) © 1988 by John Wiley & Sons, Inc. cce 0735-1232/88/020013-18$04.00 Genericity versus Inheritance define elements as extensions or restrictions of pre Unconstrained Genericity viously defined ones. 1 Both methods apply some form of polymor In its simplest form, unconstrained genericity phism, a notion that may be defined as the ability may be seen as a technique to bypass the unneces· to define program entities that may take more than sary requirements imposed by static type checking, 1 one form. A simple form of polymorphism, used in Consider the example of a simple procedure both cases, is overloading, the ability to attach more for exchanging the values of two variables. In a Ian· F than one meaning to the same name, ambiguities guage which is not statically typed, such as Lisp, we being resolved by examining the context of each oc would write something like the following, syntactic currence of the name, either at compile time (for differences notwithstanding: statically typed languages) or at run time. c Although the two approaches may be applied procedure swap (x, y) is outside the strict realm of programming, for example t local to specification or design languages, we shall confine begin our study to programming languages. In this field, t : = x; x : = y ; y : = t; genericity is most notably present in Ada; inheri end swap E tance is a feature of object-oriented languages and 1\ was introduced by Simula 67. The type of the elements to be swapped and Ada and object-oriented languages have until of the local variable t does not have to be specified, now aroused interest in rather different communi However, this may be too much freedom since a call [ ties and it is not surprising that no comparative of the form swap (a, b), where a is, say, an integer! analysis seems to have been published. (The only and b a character string, will not be prohibited even related work that we know of is the as yet unpub though it is probably an error. 3 lished, more theory-oriented article by Cardelli and To address this issue, statically typed Ian· Wegner [6], of which we became aware as this paper guages, such as Pascal, require programmers to ex was going to press.) However, we feel that beyond plicitly declare the types of all variables and formai I "cultural" differences the real goals pursued are the parameters, and enforce a statically checkable type same, so that it is fruitful to perform an in-depth compatibility constraint between actual and formal comparison of the technical solutions obtained on parameters in calls and between source and target both sides. in assignments. In such a language, the procedure to exchange the values of two variables of type T becomes: GENERICITY procedure T_swap (x, y: 1in out T) is tT Genericity as offered by Ada is present in few begin other programming languages (examples include CLU t : = x; x : = y ; y : = t; [10] and LPG [2]), but is offered by several formal end swap specification languages, such as Z [1], Clear [5], OBJ2 [9], and LM [15]. A variant of this approach was Demanding that T be specified as a single type developed in connection with the language ML [16, averts type incompatibility errors, but has the un 7] and has been integrated into a number of func pleasant consequence of requiring a new procedure tional languages. declaration for each type for which a swap operation We shall concentrate on the Ada form, re is needed; in the absence of overloading, a different stricting ourselves to type genericity~ that is to say name must be assigned to each such procedure, for the ability to parameterize a software element (in example int_swap, str _swap and so on. Such mul Ada, a package or subprogram) by one or more types. tiple declarations lengthen and obscure programs. Generic parameters have other, less interesting uses The example chosen is particularly bad since all the in Ada, such as parameterized dimensions for arrays. declarations will be identical except for the two oc We shall distinguish between unconstrained currences of T. genericity, whereby no specific requirement is im Static typing may be considered too restrictive posed on generic parameters, and constrained ge here: the only real requirement is that the two actual nericity, whereby a certain structure is required. parameters passed to any call of swap should be of 14 Journal of Pascal, Ada, & Modula-2, March/Apri11988 Genericity versus Inheritance the same type; and that their type should also be portant applications of packages, and the only one applied to the declaration of the local variable t. considered in this article, is data abstraction: each A language with genericity provides a tradeoff package contains the implementation of a type and between too much freedom, as with untyped lan of the operations applicable to elements of that type. guages, and too much restraint, as with Pascal. In Ada packages may be declared with generic such a language, one may declare T as a generic type parameters. For example, the following package pro parameter to the swap procedure. In quasi-Ada, the vides stacks of elements of an arbitrary type T procedure may be declared as follows generic generiC type T is private; type T is private; package STACKS is procedure swap (x, y: 1in out T) is type STACK (size: POSITIVE) is tT record begin space: array (1 .. size ) of T; t : = x; x : = y ; y : = t; index: NATURAL end swap end record; function empty (s: 1in STACK) The only difference with real Ada is that we return BOOLEAN; have merged together, for ease of presentation, the procedure push (t: 1in T; s: 1in out STACK); two parts of an Ada subprogram declaration, header procedure pop (s: 1in out STACK); and body; their separation in Ada comes from a con function top (s: 1in STACK) return T; cern for information hiding, orthogonal to this end STACKS discussion. The generic ... clause introduces type param We have given only the public part ("specifi eters. By specifying T as "private", the writer of this cation") of the package; the package implementation procedure allows himself to apply to objects of type ("body"), which describes the subprogram bodies, must T (x, y, and t) operations available on all types, such be declared separately. For technical reasons having as assignment or comparison, and these only. to do with the problems of Ada compilation, the im A declaration such as the above does not ac plementation of the types supported by a package, tually introduce a procedure but rather a procedure such as STACK here, is given in the public part.