Sei sulla pagina 1di 10

-85-

EIFFEL:

PROGRAMMING FOR REUSABILITY AND EXTENDIBILITY

Bertrand Meyer

Interactive Software Engineering, Inc.


270 Storke Road, Suite 7, Goleta, CA. 93117 - (805) 685-1006

1 - Introduction run to concentrate on these two factors, and they


were indeed paramount in the design of Eiffel.
Eiffel is a language and environment intended for Other design goals also played a significant part.
the design and implementation of quality software in Helping programmers ensure correctness and
production environments. The language is based on reliability of their software is of course a prime
the principles of object-oriented design, augmented concern. Portability was one of the requirements on
by features enhancing correctness, extendibility and the implementation. Finally, efficiency cannot be
efficiency; the environment includes a basic class neglected in a tool that is aimed at practical,
library and tools for such tasks as automatic medium- to large-scale developments.
configuration management, documentation and
debugging.
Beyond the language and environment aspects, 3 - Object-oriented design
Eiffel promotes a method of software construction
by combination of reusable and flexible modules. To achieve reusability and extendibility, the
The present note is a general introduction to principles of object-oriented design seem to provide
Eiffel. More detailed informatioo [1, 2, 3] is the best known technical answer to date. This note is
available. not the place to discuss these principles in depth.
We shall simply offer a definition of this notion: as
discussed here, object-oriented design is the
2 - Design principles construction of software systems as structured
collections of abstract data type implementations.
The following points are worth noting in this
Software quality is a tradeoff between many definition:
factors [4]. In the current state of the software
industry, some of these factors appear worth a • the emphasis is on structuring a system around
the objects it manipulates rather than the functions
particular effort. One is reusability, or the ability to
it performs on them, and on reusing whole data
produce software components that may be used in
structures, together with the associated operations,
many different applications; observation of
rather than isolated procedures.
programmers shows that many of the same program
patterns frequently recur, but that actual reuse of - Objects are described as instances of abstract
program modules is much less widespread than it data types - that is to say, data structures known
ought to be. Another important factor is from an official interface rather than through their
extendibility: although software is supposed to be representation.
" s o f t " , it is notoriously hard to modify software ® The basic modular unit, called the class,
systems, especially large ones. describes the implementation of an abstract data
As compared to other quality factors, reusability type (not the abstract data type itself, whose
and extendibility play a special rble as their specification would not necessarily be executable).
satisfaction means that less software has to be o The word collection reflects how classes should
written, and thus, presumably, that more time may be designed: as units which are interesting and
be devoted to the other goals (such as efficiency, useful on their own, independently from the
ease of use etc.). Thus it may pay off in the long systems to which they belong. Such classes may

SIGPLAN Notices, V22 #2, February 1987


-86-

then be reused in many different systems. System 4 - Classes


construction is viewed as the assembly of existing
classes, not as a top-down process starting from We first introduce a typical class. As mentioned
scratch. above, a class represents the implementation of an
® Finally, the word structured reflects the abstract data type, that is to say a class of data
existence of important relationships between structures known through an official interface. A
classes, particularly the multiple inheritance simple example would be a a bank account. Let
relation. ACCOUNT be the corresponding class. Before we
Following Simula 67 [5], several object-oriented show the class, we first describe how it would be
languages have appeared in recent years, such as used; such a use has to be in another class, say X,
Smalltalk [6], extensions of C such as C++ [7] and as classes are the only program unit in Eiffel.
Objective C [8], of Pascal such as Object Pascal [9], To use ACCOUNT, class X may introduce an
of Lisp such as Loops [10], Flavors [11] and Ceyx entity and declare it of this type:
[12]. Eiffel shares the basic properties of these
accl: ACCOUNT
languages but goes beyond them in several respects,
by offenng multiple inheritance (which, of the The term "entity" is preferred here to "variable"
systems quoted, is only available in recent versions as it corresponds to a more general notion. An entity
of Smalltalk, on an experimental basis, and in the declared of a class type, such as accl, may at any
Lisp extensions), genetic classes, static type time during execution refer to an object; an entity
checking (whereas most existing languages are either which does not refer to any object is said to be void.
untyped or offer dynamic checking only) and By default (at initialization) entities are void; objects
facilities for redefinition and renaming (see below). must be created explicitly, by an instruction
Furthermore, Eiffel combines the object-oriented
accl.Create
heritage with a strong software engineering
influence, through facilities for information hiding, which associates accl with the newly created object
expression of formal program properties (assertions, (see figure 1). Create is a predefined "feature" of
invariants) and a strict naming policy. Finally the the language.
language comes with an environment geared towards
the development of sizable software in production
environments.
The rest of this presentation inlroduces the main
language features informally, through a set of
examples, and describes the pnncipal aspects of the
implementation and environment.
0
One remark is in order on the size of the Figure 1: Entity and associated object
language. Eiffel includes more than presented in this
introduction, but not much more; it is a small
Once acc 1 has been associated with an object,
language, comparable m size (by such an
approximate measure as the number of keywords) to one may apply to it the features defined in the
corresponding class. Examples are:
Pascal. Thus Eiffel belongs to the class of
languages which programmers can master entirely accl.open ("John");
(as opposed to languages of which most accl.deposit (5000);
programmers know only a subset). Yet it is if accl.may_withdraw (3000) then
appropriate for the development of significant accl.withdraw (3000)
software systems, as evidenced by our own end;
experience with such programs as C~page [13] print (accl.balance )
(which, at the time of this writing, is a 45,000-line
Eiffel system) and other examples. All feature applications use the dot notation:
entity_name.featurename. There are two kinds of
features: routines (as open, deposit, may_withdraw
or withdraw), that is to say operations; and
attributes, that is to say data items associated with
objects of the class.
-87-

Routines are further divided into procedures maywithdraw (sum: INTEGER): BOOLEAN is
(actions, which do not return a value) and functions -- Is it permitted to withdraw sum
(which return a value). Here may_withdraw is a -- from the account?
function with an integer parameter, returning a do
boolean result; the other three routines invoked are Result := (balance >= minimunubalance)
procedures. end ; -- deposit
The above extract of class X does not show end -- class ACCOUNT
whether, in class ACCOUNT, balance is an attribute This class includes two clauses: feature, which
or a function without parameters. This ambiguity is describes the features of the class, and export,
intentional. A class such as X , said to be a client of which simply fists those features which are available
ACCOUNT, does not need to know how a balance is to clients of the class. Non-exported features are said
obtained: it could be stored as attribute of every to be secret. Here procedure add is secret, so that
account object, or re-computed by a function, accl.add (-3000) would have been illegal in X.
whenever requested, from other attributes such as Similarly, attribute minimumbalance is secret.
the list of previous deposits and withdrawals. (Selective export of a feature to some classes only is
Deciding on one of these implementations is the also possible.)
business of class ACCOUNT, not anybody else's. Let us examine the features in sequence.
Having shown class usage, we now present the Routines are distinguished from attributes by having
definition of the class itself, which might look like a clause of the form is...do...end. Thus balance is
the following. Following the Ada convention, fine in fact an attribute. The clause is 1000 introduces
segments beginning with -- are comments. minimumbalance as a constant attribute, which will
class ACCOUNT export not occupy any physical space in objects of the
open, deposit, may_withdraw, class. Non-constant attributes such as balance do
use space for each object of the class; they are
withdraw, balance, owner
similar to components of a record in Pascal.
feature
balance: INTEGER . Attributes balance and minimum_balance are
declared of type INTEGER. Eiffel is strongly typed:
minimum_balance: INTEGER is 1000 ;
every entity is declared of a certain type. A type is
owner: STRING ; either simple, that is to say one of INTEGER,
assign_owner (who: STRING) is REAL, CHARACTER and BOOLEAN, or a class.
-- Assign the account to owner who Arrays and strings belong to the second category;
do they are described by predefined system classes,
owner := who ARRAY and STRING, treated exactly as user-defined
end ; -- open classes with one exception: a special notation, as in
"John", is available to denote literal string constants.
add (sum: INTEGER) is
-- Add sum to the balance Automatic initialization is ensured by the
language definition, so that the initial balance of an
-- (Secret procedure)
account object will be zero after a Create. Numeric
do
attributes are initialized to zero, booleans to false,
balance := balance+sum
characters to the null character; those of class types
end ; -- deposit
are initially void.
deposit (sum: INTEGER) is
The other five features are straightforward
-- Deposit sum into the account
routines. The first four are procedures, the last one
do
(may_withdraw) a function returning a boolean
add (sum)
value; note that the special variable Result denotes
end ; -- deposit
the function result. It is initialized on function entry
withdraw (sum: INTEGER) is to the default value of the appropriate type, as
-- Withdraw sum from the account defined above.
do To properly understand the routines, it is
add (-sum) necessary to remember that in an object-oriented
end ; -- withdraw languages any operation is relative to a certain
object. In an external client invoking the operation,
this object is specified by writing the corresponding
-88-

entity on the left o f the dot, as accl in class ACCOUNT export .... (as before)
accl.open ("John"). Within the class, however, the feature
"current" object to which operations apply usually -- Attributes as before:
remains implicit, so that unqualified references, such --balance, minimumbalance, owner
as owner in procedure assign_owner or add in assign_owner ..... -- as before ;
deposit, mean "the owner attribute or add routine
relative to the current object". The special variable add ..... -- as before ;
Current may be used, if needed, to explicitly denote deposit (sum: INTEGER) is
this object. Thus the unqualified occurrences of add -- Deposit sum into the account
appearing in the above class are equivalent to require
Current.add. sum >= 0
In summary, this simple example shows the basic do
structuring mechanism of the language, the class. A add (sum)
class describes a data structure, accessible to clients ensure
through an official interface comprising some of the balance = old balance + sum
class features. Features are implemented as end ; -- deposit
attributes or routines; the implementation of withdraw (sum: INTEGER) is
exported features may rely on other, secret ones. -- Withdraw sum from the account
require
sum >= 0 ;
5 - Assertions sum <= balance - minimum_balance
do
It was said at the outset that classes are abstract add (-sum)
data type implementations. However an abstract ensure
data type is defined not just by a list of available balance = old balance - sum
operations, but also by the formal properties of these end ; -- withdraw
operations, which do not appear in the above may_withdraw ..... -- as before
example.
Create (initial: INTEGER) is
Eiffel indeed enables and encourages
require
programmers to express formal properties of classes
initial >= minimum_balance
by writing assertions, which may in particular
do
appear in the following positions:
balance := initial
• routine preconditions express conditions that end -- Create
must be satisfied whenever a routine is called. For
invariant
example withdrawal might only be permitted if it
balance >= minimum_balance
keeps the account's balance on or above the
end -- class ACCOUNT
minimum. Preconditions are introduced by the
keyword require. The old.., notation may be used in an ensure
clause, with a self-explanatory meaning.
• Routine postconditions, introduced by the
keyword ensure, express conditions that are The reader will have noted that a Create
guaranteed to be true on routine return (if the procedure has been added to the features of the
precondition was satisfied on entry). class. The reason is the following. Under the
previous scheme, an account was created by, say,
• Class invariants must be satisfied by objects of
accl.Create. Because of the initialization rules,
the class at all times, or more precisely after
balance is then zero and the invariant is violated. If
object creation and after any call to a routine of
a different initialization is required or, as here, an
the class. They are described in the invariant
initialization depending on a parameter supplied by
clause of the class and represent general
the client, then the class should include a procedure
consistency constraints that are imposed on all
called Create. Object creation will be obtained by
routines of the class.
writing, say
Our ACCOUNT class may be rewritten with
appropriate assertions: accl.Create (5500)
whose effect is to allocate the object (as in the
default Create) and then to execute the procedure
-89-

called Create in the class, with the given actual 6 - Generic classes
parameter. This example call is correct as the
precondition is satisfied and the invariant will hold Building software components (classes) as
after the call implementations of abstract data types yields
Note that procedure Create, when explicitly systems with a solid architecture but does not in
provided, is recognized by the compiler as special; it itself suffice to ensure reusability and extendibility.
is automatically exported and should not be included This section and the next two describe Eiffel
in the export clause. techniques for making the components as general
Assertions, as they appear in preconditions, and flexible as possible.
postconditions and invariants, should primarily be The first technique is genericity, which exists
viewed as powerful tools for documenting under different forms in Ada and CLU but is fairly
correctness arguments: they serve to make explicit new to object-oriented languages. Classes may be
the assumptions on which programmers rely when declared with generic parameters representing types.
they write program fragments that they believe are For example, the following classes are part of the
correct. In this respect, assertions are formalized basic Eiffel library:
comments. For debugging purposes, the Eiffel ARRAY [T]
environment also makes it possible to monitor LIST [T]
assertions at run-time, producing a message if an LINKED_LIST [T]
assertion is found to be violated.
They respectively describe one-dimensional
Syntactically, expressions are boolean expressions, arrays, general lists (without commitment as to a
with a few extensions (like the old notation). The specific representation) and lists in linked
semicolon (see the precondition to withdraw) is representation. All have a formal generic parameter
equivalent to an " a n d " , but permits individual T representing an arbitrary type. To actually use
identification of the components, useful for these classes, one provides actual generic
producing informative error messages at run-time. parameters, which may be either simple or class
It must be pointed out that assertions are not a types, as in the following declarations:
technique for exception handling. An exception (in
il: LIST [INTEGER];
the CLU or Ada sense) is a run-time situation which aa: ARRAY [ACCOUNT];
the programmer prefers to handle in code separate aal: LIST [[ARRAY [ACCOUNT]] --etc.
from the main flow of control, but which (for the
very reason that the program is prepared to deal An earlier article [2] discussed the rble of
with it) falls within the scope of the specification. In genericity in comparison to inheritance and
contrast, an assertion denotes a condition that should explained their combination in Eiffel, especially in
always be satisfied at the given control point; for the context of strict type checking. The solution
example, a precondition describes the requirements involves the notion of "declaration by association",
for a routine body to be applicable. Assertion not addressed here.
violation reflects a progranlming error, not an
exceptional but planned situation from which it is
7 - Multiple inheritance
possible to recover gracefully.
Eiffel offers no specific mechanism for exception
handling. In our experience, standard algorithmic Multiple inheritance is a key technique for
techniques are appropriate for dealing with reusability. The basic idea is simple: when defining
exceptional conditions. Although we accept differing a new class, it is often fruitful to introduce it by
views on the question, we considered this facility to combination and specialization of existing classes
rather than as a new entity defined from scratch.
be of secondary importance and preferred to keep it
out of the language in the interest of design A simple example is provided by the classes of
simplicity. Encouraging programmers to express the basic library mentioned above. LIST, as
correctness arguments precisely through well-placed indicated, describes lists of any representation. One
assertions appeared much more relevant. possible representation for lists with a fixed number
of elements uses an array. Such a class will be
defined by combination of LIST and ARRAY, as
follows:
-90-

class F I X E D L I S T [T] export .... To further ensure that the multiple inheritance
inherit mechanism is not misused, the invariants of all
LIST [T]; parent classes automatically apply to a newly
ARRAY [T] defined class. Thus classes may not be combined if
feature their invariants are incompatible.
... Specific features of fixed-size lists ...
end -- class FIXED_LIST
The inherit.., clause lists all the "parents" of the 8 - Polymorphism
new class (which is said to be their "heir"). Thanks
to this clause, all the features and properties of lists One important aspect of inheritance is that it
and arrays are applicable to fixed lists as well. This enables the definition of flexible program entities
simple idea makes it possible to achieve remarkable that may refer to objects of various forms at run-
economies of programming, of which we feel the time (hence the name "polymorphic").
effects daily in our experience of Eiffel software This possibility is one of the distinguishing
development. (Inheritance was introduced by Simula features of object-oriented languages. In Eiffel, it is
67. In Simula, however, as in many other object- reconciled with static typing. The underlying
oriented languages, inheritance is not multiple: language convention is simple: an assignment of the
classes may have at most one parent.) form a := b is permitted not only if a and b are of
The very power of the mechanism demands the same type, but more generally if a and b are of
adequate means to control its effects. In Eiffel, no class types A and B such that B is a descendant of
name conflict is permitted between inherited A, where the descendants of a class include itself,
features. Since such conflicts will inevitably arise in its heirs, the heirs of its heirs etc. (The inverse
practice, especially in the case of software notion is "ancestor".)
components brought in by independent developers, This corresponds to the intuitive idea that a value
the language provides a technique to remove them: of a more specialized type may be assigned to an
explicit renaming, as in entity of a less specialized type - but not the
class C export.., inherit reverse. (As an analogy, consider the fact that if I
A r e n a m e x as xl, y as yl; request vegetables, getting green vegetables is fine,
B r e n a m e x as x2, y as y2 but if I ask for green vegetables, receiving a dish
feature... specified as just "vegetables" is not acceptable, as
Here the inherit clause would be illegal without it could include, say, cauliflower.)
renaming, since the example assumes that both A What makes this possibility particularly powerful
and B have features named x and y. is the complementary facility: feature redefinition.
Renaming also serves to provide more appropriate A feature of a class may be redefined in any
feature names in heirs. In another example from the descendant class; the type of the redefined feature (if
basic library, class TREE IT] is defined by an attribute or a function) may be redefined as a
inheritance from LINKED_LIST [T] and descendant type of the original feature, and, in the
LINKABLE [T], the latter describing dements of case of a routine, its body may also be replaced by a
linked lists. The idea is that a tree is a list (as it has new one.
subtrees, to which the usual list operations of Assume for example that a class POLYGON,
insertion, change, deletion, traversal etc. apply), as describing polygons, has among its features an array
well as a list element, as it may itself be inserted as of points representing the vertices and a function
subtree into another tree. (The class definition thus perimeter returning a real result, the perimeter of
obtained is simple and compact, while covering a the current polygon, obtained by summing the
rich set of tree manipulation primitives which have successive distances between vertices. An heir of
proved sufficient in such different contexts as a POLYGON may be:
multiple-windowing screen handler and a syntax-
directed editor.) In the inheritance clause, the feature
empty of linked lists, a boolean-valued function
which determines whether a list is empty, itself
inherited from LIST, is renamed is_leaf to conform
to standard tree terminology.
-91-

class RECTANGLE export ... inherit or circumstance) is invariably incremental.


POLYGON redefine perimeter Neither do the generic and overloading facilities
feature of Ada offer the kind of polymorphism shown here,
-- Specific featvxes of rectangles, such as: as they do not support a programming style in which
side]: REAL; side2: REAL; a client module may issue a request meaning:
perimeter: REAL is "compute the perimeter of p, using the algorithm
-- Rectangle-specific version appropriate for whatever form p happens to have
do when the request is executed".
Result := 2 • (side1 + side2) This mechanism is more disciplined in Eiffel than
end; -- perimeter in most other object-oriented languages. First,
... other RECTANGLE features ... feature redefinition, as seen above, is explicit.
Here it is appropriate to redefine perimeter for Second, because the language is typed, the compiler
rectangles as there is a simpler and more efficient may always check statically whether a feature
algorithm. Note the explicit redefine subclause application a.f is correct; in contrast, languages
(which would come after the rename if present). such as Smalltalk and its descendants (such as
Other descendants of POLYGON may also have Objective-C) defer checks until run-time and hope
their own redefinitions of perimeter. The version to for the best: if an object "sends a message" to
use in any call is determined by the run-time form another (Smalltalk terminology for calling a routine),
one just expects that the class of the receiving
of the parameter. Consider the following class
object, or one of its ancestor classes, will happen to
fragment:
include an appropriate "method" (Smalltalk term
p: POLYGON; r: RECTANGLE; for routine); if not, a run-time error will occur.
........ p.Create; r.Create; ........ Such en~rs may not happen during the execution of
if c then p := r end; a correctly compiled Eiffel system.
print (p.perimeter)
A further disadvantage of the Smalltalk approach
The assignment p := r is vafid because of the is that it may imply costly run-time searches, as a
above rule. If condition c is false, p will refer to an requested method may not be defined in the class of
object of type POLYGON when p.perimeter is the receiving object but inherited from a possibly
evaluated, so the polygon algorithm will be used; in remote ancestor. What, on the other hand, may be
the opposite case, however, p will dynamically refer said in favor of the interpretive, dynamic Smalltalk
to a rectangle, so that the redefined version of the approach is that it makes it easy, in the Lisp
feature will be applied. tradition, to modify the software while it is running,
This technique provides a high degree of for example by providing a missing method; such
flexibility and generality. The remarkable advantage facilities, useful for exploratory programming, are
for cfients is the ability to request an operation (here harder to provide in a compiler-oriented system
the computation of a figure's perimeter) without which also includes correctness, reliability and
knowing what version of the operation will be efficiency among its design goals.
selected; the selection only occurs at run-time. This Another tool for controlling the power of the
is crucial in large systems, where many variants of redefinition mechanism is provided in Eiffel by
operations may be available, and each component of assertions. If no precautions are taken, redefinition
the system needs to be protected against variant may be dangerous: how can a cfient be sure that
changes in other components. evaluation of p.perimeter will not in some cases
There is no equivalent to this possibility in non- return, say, the area? One way to maintain the
object-oriented languages. Note for example that semantic consistency of routines throughout their
discrimination on records with variants, as permitted redefinitions is to use preconditions and
by Pascal or Ada, is of a much more restrictive postconditions, which are binding on redefinitions.
nature, as the list of variants of a record type is More precisely, any redefined version must satisfy a
fixed: any extension may invafidate existing code. In weaker or equal precondition and ensure a stronger
contrast, inheritance is open and incremental: an or equal postcondition than in the original. Thus, by
existing class may always be given a new heir (with making the semantic constraints explicit, routine
new and/or redefined features) without itself being writers may limit the amount of freedom granted to
changed. This is crucial in the development of eventual redefiners.
practical software systems which (whether by design
-92-

This concludes the overview of the language. As o There is almost never any duplication of code.
it is well known that a programming language is in Again this was difficult to achieve with multiple
practice no better than its implementation, we inheritance and genericity: the implementation of
conclude with a brief description of the Eiffel multiple inheritance included in recent versions of
compiler and associated environment. Smalltalk [14] duplicates codes for parent classes
other than the first, precisely to avoid the graph
traversal mentioned above; most implementations
9 - The implementation of generic packages in Ada systems also duplicate
code for various generic instances of a program
The current implementation of Eiffel runs on unit. The only case in which we do duplicate code
various versions of Unix (System V, 4.2BSD, is a rather rare and special occurrence,
Xenix). It is based on translation from Eiffel to C, "repeated" inheritance with feature duplication,
then C to machine code using the resident C not described here.
compiler. It may potentially be ported to any . Memory management is handled by a ran-time
environment including a C compiler and some basic system that takes care of object creation and
operating system capabilities. (system-controlled) de-allocation. Optionally, the
Note that (as the above discussion should suffice memory management system includes its own
to show) Eiffel is in no way an extension of C; C is virtual memory subsystem, which may be turned
only used as a vehicle for implementation and has off if the facilities of the underlying operating
had no influence on the language design. Other system are sufficient. Garbage collection is also
compilation techniques would be possible, but the provided; it is performed incrementally by a
use of a portable assembly language such as C as parallel process which steals as little time as it
intermediate code has obvious advantages for can from application programs [15]. (At the
transferability of the implementation. moment garbage collection is parallel on the Unix
System V version only.)
Great care has been taken to provide efficient
compilation and execution, so that the environment ® Compilation is performed on a class-by-class
would support the development of serious software. basis, so that large systems can be changed and
The following points are particularly worth noting. extended incrementally. The translation time from
Eiffel to C is usually (in our experience) between
• As was seen above, the potential for redefinition
50% and 100% of the time for the next step,
implies that a qualified routine reference, say
translation from C to machine code.
p.perimeter, may have many different
interpretations depending on the value of p at One more property of the implementation
run-time. As mentioned, this powerful facility deserves a mention: its openness. Eiffel classes are
may result in serious inefficiencies if the search meant to be interfaced with code written in other
for the appropriate routine is made at run-time, as languages. This concern is reflected in the language
seems to be necessary. The maximum length of by the optional external clause which, in a routine
such a search grows with the depth of the declaration, lists external subprograms used by the
inheritance graph, putting reusability (which tends routine. For example, an Eiffel routine for
to promote the addition of new levels of computing square roots might rely on an external
inheritance and feature redefinition) in direct function, as follows:
conflict with efficient performance. Note that the sqrt (x: REAL, eps: REAL): REAL is
situation becomes hopeless with multiple -- Square root of x with precision eps
inheritance, as not only a linear list but a require
complete graph of ancestor classes must be x>=O ; eps>O
searched at run-time. external
The Eiffel implementation always finds the csqrt (x: REAL, eps: REAL): REAL
appropriate routine m constant time; the space n a m e "sqrt" language "C"
overhead associated with this technique is do
negligible. We found this result rather difficult to Result := csqrt (x, eps)
achieve in the presence of multiple inheritance - ensure
but essential in fight of the previous discussion. abs (Result ^ 2 - x) <= eps
Whether you have one or one million routines in end -- sqrt
your system, a.x always takes the same time.
-93-

The optional name.., subclause caters to the compiled, the system automatically looks for all
various naming conventions of other programming classes on which C depends directly or indkectly
languages. (as client or heir), and re-compiles those whose
This mechanism makes it possible to use external compiled versions have become obsolete. Unix
routines without impacting the conceptual programmers will recognize this facility as giving
consistency of the Eiffel classes. Note in particular the power of Make without programmer-written
how the C function sqrt is granted a more dignified makefiles. This is far from being a trivial problem,
status as Eiffel routine with the addition of a as the dependency relations are complex (a class
precondition and a postcondition. may be, say, a client of one of its descendants) and,
in the case of the client relation, may involve cycles.
This facility is essential in view of the design
However the solution to this problem completely
objectives listed in section 2: an environment
frees programmers from having to keep track of
promoting reusability should enable reuse of
changed modules to maintain the consistency of
software written prior to its introduction, not just of
their systems. Note that the algorithm used is able to
future software to be developed with it. Beyond this
avoid many unneeded recompilations by detecting
remark, the "external" construct lies at the basis of
that a modification made to a class has not impacted
one of the applications of Eiffel: as an integrating
its interface; this has proved very important in
mechanism for components written in other
practice, as it avoids triggering a chain reaction of
languages. An example might be scientific software:
re-compilations in a large system when the
although numerical programs will benefit just as
implementation of a feature is changed in a low-
much as others from such structuring mechanisms as
level class.
classes, multiple inheritance, geneficity, export
controls, assertions etc., programmers may prefer to The environment also contains debugging tools:
code the actual bodies of numerical routines in a tools for run-time checking of assertions; a tracer
language specifically designed for this purpose, and and symbolic debugger; a viewer for interactive
package them cleanly in Eiffel classes. exploration of the object structure at run-time.
This application is one of the three main intended A documentation tool, short, produces a summary
uses of Eiffel. The second is the most obvious, version of a class showing only its official
namely as a tool covering the whole design and information: the exported features only and, in the
implementation process; this is how we apply Eiffel case of routines, only the header, precondition and
at Interactive Software Engineering. The third may postcondition.
appeal to users who, because of external A postprocessor, ep, performs various optional
requirements, must produce final programs in some modifications on the generated C code: removal of
other language (such as Ada); it consists in unneeded routines, simplification of calls to non-
employing Eiffel as an object-oriented PDL polymotphic routines, packaging of the entire
(Program Design Language) covering the part of the generating code as a library of routines callable from
process extending from global to detailed design, other programs, "obscuring" of the C code (by
and translating the result into the required default, the generated C code is fairly readable, and
implementation language. Eiffel may even be used it is not too difficult to find the correspondence with
earlier, at the specification stage, thanks in particular the original Eiffel; "obscured" code will make it
to a facility not described in this article, deferred very hard to understand the algorithms). The last
routines. (A deferred routine has no body: two options are particularly interesting for software
implementations must be provided in descendants of implementors who use Eiffel for the development of
its class; semantics may, however, be specified by a packages that will be delivered to their customers in
precondition and a postcondition.) standard C form.
Finally the environment includes a set of basic
classes covering some of the most important data
10 - The environment structure implementations. Our goal is to extend
this library so as to cover the most common patterns
The construction of systems in Eiffel is supported of everyday programming.
by a set of development tools.
Most important are the facilities for automatic
configuration management integrated into the
compilation commands. When a class C is
-94-

11 - Conclusion Addison-Wesley, Reading (Massachusets),


1983.
A number of individual concepts embodied in 7. Bjame Stroustrup, The C++ Programming
Eiffel were present in previous languages; our most Language, Addison-Wesley, Menlo Park
important conscious debts are (in order of decreasing (California), 1986.
influence) to Simula 67, Ada and Alphard. Among 8. Brad J. Cox, Object-Oriented Programming: An
the new contributions are, from the language Evolutionary Approach, Addison-Wesley,
standpoint, the safe treatment of multiple inheritance Reading (Massachusetts), 1986.
through renaming, the combination between
9. Larry Tesler, "Object Pascal Report,"
genericity and inheritance, disciplined polymorphism
by expficit redefinition, the integration of the
Structured Language World, vol. 9, no. 3, 1985.
assertion/invariant mechanism with multiple 10. Daniel G. Bobrow and M.J. Stefik, LOOPS: an
inheritance, a clean interface with external routines, Object-Oriented Programming System for
and the introduction of full static typing into an Interlisp, Xerox PARC, 1982.
object-oriented language. From the implementation 11. H.I. Cannon, "Flavors," Technical Report,
standpoint, a number of our solutions are original: MIT Artificial Intelligence Laboratory,
constant-time routine access, separate compilation Cambridge (Massachussets), 1980.
with automatic configuration management in an
12. Jean-Marie Hullot, "Ceyx, Version 15: I - une
object-oriented world, support for debugging and
Initiation," Rapport Technique no. 44, INRIA,
documentation, support for the preparation of
Rocquencourt, Et6 1984.
defiverable software packages.
13. Bemand Meyer, "Ctpage: Towards Computer-
More generally, we think that Eiffel is the first
Aided Design of Software," Computer
language to combine the powerful ideas of object-
Language, vol. 3, no. 9, pp. 43-53, September
oriented languages with the modem concepts of
1986.
software engineering; these results have been made
available to practicing software developers in an 14. Alan H. Boming and Daniel H. H. Ingalls,
environment offering the facilities that are required "Multiple Inheritance in Smalltalk-80," in
to develop serious software. Proceedings of AAAI-82, pp. 234-237, 1982.
15. Edsger W. Dijkstra, Leslie Lamport, A.J.
References Martin, C.S. Scholten, and E.F.M. Steffens,
"On-the-Fly Garbage Collection: An Exercise
1. Bertrand Meyer, Eiffel: a Language for in Cooperation," Communications of the ACM,
Software Engineering, Technical Report vol. 21, no. 11, pp. 966-975, November 1978.
TRCS85-19, University of California, Santa
Barbara, Computer Science Department,
November 1985 (Revised, August 1986). Trademarks: Unix (AT&T Bell Laboratories); Ada
(AJPO); Objective C (Productivity Products
2. Bertrand Meyer, "Genericity versus International); Smalltalk (Xerox); Eiffel (Interactive
inheritance," in Proceedings of ACM Software Engineering, Inc.).
Conference on Object-Oriented Programming
Systems, Languages and Applications, pp. 391-
405, Portland (Oregon), September 29 - October
2, 1986.
3. Bertrand Meyer, "Software Reusability: the
Case for Object-Oriented Design," Report TR-
86-06, Interactive Software Engineering, Santa
Barbara (California), 1986.
4. James McCall, (Ed.) Factors in Software
Quality, General Electric, 1977.
5. Graham Birtwistle, Ole-Johan Dahl, Bjom
Myrhaug, and Kristen Nygaard, Simula Begin,
Studentliteratur and Auerbach Publishers, 1973.
6. Adele Goldberg and David Robson, Smalltalk-
80: The Language and its Implementation,

Potrebbero piacerti anche