Jump to content

Eiffel (programming language): Difference between revisions

From Wikipedia, the free encyclopedia
Content deleted Content added
m Overview: Removed stray bracket
Other language mechanisms: Removed blue font colouring
Line 76: Line 76:
An important property of Eiffel is that a class is fundamentally a mapping from feature names to features. More plainly said this means that one name, within one class, means one thing. This keeps things simple and in particular is what makes the multiple inheritance mechanism possible (see below).
An important property of Eiffel is that a class is fundamentally a mapping from feature names to features. More plainly said this means that one name, within one class, means one thing. This keeps things simple and in particular is what makes the multiple inheritance mechanism possible (see below).


Names can, of course, be reused in different classes, but in a given class if you need another feature you'll have to invent another name. This is really no limitation since the conventional kinds of [[overloading]] are, in an object-oriented perspective, applied to different classes. For example if you want to have several versions of <font color=blue>"+"</font>:
Names can, of course, be reused in different classes, but in a given class if you need another feature you'll have to invent another name. This is really no limitation since the conventional kinds of [[overloading]] are, in an object-oriented perspective, applied to different classes. For example if you want to have several versions of "+":




<font color=blue>''a'' + ''b''</font> for <font color=blue>''a'', ''b'': ''INTEGER''</font>
''a'' + ''b'' for ''a'', ''b'': ''INTEGER''
<font color=blue>''a'' + ''b''</font> for <font color=blue>''a'', ''b'': ''REAL''</font>
''a'' + ''b'' for ''a'', ''b'': ''REAL''
<font color=blue>''a'' + ''b''</font> for <font color=blue>''a'', ''b'': ''VECTOR'' [''INTEGER'']</font>
''a'' + ''b'' for ''a'', ''b'': ''VECTOR'' [''INTEGER'']


then in Eiffel it simply means that the three classes involved each have a feature
then in Eiffel it simply means that the three classes involved each have a feature


<font color=blue>''plus'' '''alias''' "+" (''other'': ''XXX''): ''XXX''</font>
''plus'' '''alias''' "+" (''other'': ''XXX''): ''XXX''


where <font color=blue>''XXX''</font> is the given class (<font color=blue>''INTEGER''</font>, <font color=blue>''REAL''</font>, <font color=blue>''VECTOR'' [''G''])</font>. All the usual forms of operator overloading are thus supported; in fact the mechanism is quite extensive since (unlike in most languages) there is considerable freedom in making up new operators, as may be needed in scientific and engineering applications. What is not possible is the kind of argument overloading where a given class has both a feature <font color=blue>''f'' (''x'': ''X'')</font> and another <font color=blue>''f'' (''y'': ''Y'')</font> with the same names. Meyer has argued <ref>Bertrand Meyer: Overloading vs Object Technology, in Journal of Object-Oriented Programming (JOOP), vol. 14, no. 4, October-November 2001, available [http://se.ethz.ch/~meyer/publications/joop/overloading.pdf online]</ref> that such overloading is useless, damages readability, and complicates the language mechanism needlessly.
where ''XXX'' is the given class (''INTEGER'', ''REAL'', ''VECTOR'' [''G'']). All the usual forms of operator overloading are thus supported; in fact the mechanism is quite extensive since (unlike in most languages) there is considerable freedom in making up new operators, as may be needed in scientific and engineering applications. What is not possible is the kind of argument overloading where a given class has both a feature ''f'' (''x'': ''X'') and another ''f'' (''y'': ''Y'') with the same names. Meyer has argued <ref>Bertrand Meyer: Overloading vs Object Technology, in Journal of Object-Oriented Programming (JOOP), vol. 14, no. 4, October-November 2001, available [http://se.ethz.ch/~meyer/publications/joop/overloading.pdf online]</ref> that such overloading is useless, damages readability, and complicates the language mechanism needlessly.


===Genericity===
===Genericity===
Classes can be generic, to express that they are parameterized by types. Generic parameters appear in square brackets:
Classes can be generic, to express that they are parameterized by types. Generic parameters appear in square brackets:
<font color="blue">'''class''' ''LIST'' [''G''] ...</font>
'''class''' ''LIST'' [''G''] ...


G is known as a "formal generic parameter". (Eiffel reserves "argument" for routines, and uses "parameter" only for generic classes.) With such a declaration G represents within the class an arbitrary type; so a function can return a value of type G, and a routine can take an argument of that type:
G is known as a "formal generic parameter". (Eiffel reserves "argument" for routines, and uses "parameter" only for generic classes.) With such a declaration G represents within the class an arbitrary type; so a function can return a value of type G, and a routine can take an argument of that type:


<font color="blue">''item'': ''G'' '''do''' ... '''end'''
''item'': ''G'' '''do''' ... '''end'''
''put'' (''x'': ''G'') '''do''' ... '''end'''</font>
''put'' (''x'': ''G'') '''do''' ... '''end'''


The <font color="blue">''LIST'' [''INTEGER'']</font> and <font color="blue">''LIST'' [''WORD'']</font> are "generic derivations" of this class. Permitted combinations(with <font color="blue">''n'': ''INTEGER''</font>, <font color="blue">''w'': ''WORD''</font>, <font color="blue">''il'': ''LIST'' [''INTEGER'']</font>, <font color="blue">''wl'': ''LIST'' [''WORD'']</font>) are
The ''LIST'' [''INTEGER''] and ''LIST'' [''WORD''] are "generic derivations" of this class. Permitted combinations(with ''n'': ''INTEGER'', ''w'': ''WORD'', ''il'': ''LIST'' [''INTEGER''], ''wl'': ''LIST'' [''WORD'']) are


<font color="blue">''n'' := ''il''.''item''
''n'' := ''il''.''item''
''wl''.''put'' (''w'')</font>
''wl''.''put'' (''w'')


<font color="blue">''INTEGER''</font> resp. <font color="blue">''WORD''</font> are the "actual generic parameters" in these generic derivations.
''INTEGER'' resp. ''WORD'' are the "actual generic parameters" in these generic derivations.


It is also possible to have '''constrained''' formal parameters, for which the actual parameter must inherit from a given class, the "constraint". For example in
It is also possible to have '''constrained''' formal parameters, for which the actual parameter must inherit from a given class, the "constraint". For example in


<font color="blue">'''class''' ''HASH_TABLE'' [''G'', ''KEY'' -> ''HASHABLE'']</font>
'''class''' ''HASH_TABLE'' [''G'', ''KEY'' -> ''HASHABLE'']


a derivation <font color="blue">''HASH_TABLE'' [''INTEGER'', ''STRING'']</font> is valid only if <font color="blue">STRING</font> inherits from <font color="blue">''HASHABLE''</font> (as it it indeed does in typical Eiffel libraries). Within the class, having <font color="blue">KEY</font> constrained by <font color="blue">''HASHABLE''</font> means that for <font color="blue">''x'': ''KEY''</font> it is possible to apply to <font color="blue">x</font> all the features of <font color="blue">''HASHABLE''</font>, as in <font color="blue">''x''.''hash_code''</font>.
a derivation ''HASH_TABLE'' [''INTEGER'', ''STRING''] is valid only if STRING inherits from ''HASHABLE'' (as it it indeed does in typical Eiffel libraries). Within the class, having KEY constrained by ''HASHABLE'' means that for ''x'': ''KEY'' it is possible to apply to x all the features of ''HASHABLE'', as in ''x''.''hash_code''.


===Inheritance basics===
===Inheritance basics===
Line 121: Line 121:
===Operator and bracket syntax===
===Operator and bracket syntax===
===Lexical and syntax properties===
===Lexical and syntax properties===
Eiffel is not case-sensitive. The tokens ''MaKe'', ''make'', and ''MAKE'' all refer to the same identifier. Style standards, however, prescribe the use of all-capitals for class names, all-lower-case for feature names, and initial capitals for constants. The recommended style also suggests underscore to separate components of a multi-word identifier, as in <font color=blue>''average_temperature''</font>.
Eiffel is not case-sensitive. The tokens ''MaKe'', ''make'', and ''MAKE'' all refer to the same identifier. Style standards, however, prescribe the use of all-capitals for class names, all-lower-case for feature names, and initial capitals for constants. The recommended style also suggests underscore to separate components of a multi-word identifier, as in ''average_temperature''.


Eiffel's syntax can be parsed without requiring end-of-instruction markers. The use of semicolons as instruction terminators or as instruction separators is left to the discretion of the programmer. Putting a semicolon in or leaving one out makes no difference, except in the unusual case of an instruction starting with a left parenthesis. Most Eiffel programmers choose to omit semicolons except when putting multiple statements on a line.
Eiffel's syntax can be parsed without requiring end-of-instruction markers. The use of semicolons as instruction terminators or as instruction separators is left to the discretion of the programmer. Putting a semicolon in or leaving one out makes no difference, except in the unusual case of an instruction starting with a left parenthesis. Most Eiffel programmers choose to omit semicolons except when putting multiple statements on a line.
Line 127: Line 127:
In contrast to most [[curly bracket programming language]]s, Eiffel makes a clear distinction between expressions and instructions. This is in line with the [[Command-Query Separation]] principle of the Eiffel method.
In contrast to most [[curly bracket programming language]]s, Eiffel makes a clear distinction between expressions and instructions. This is in line with the [[Command-Query Separation]] principle of the Eiffel method.


The specification of Eiffel includes guidelines for displaying software texts in typeset formats: keywords in bold, user-defined identifiers and constants are shown in <font color=blue>''italics''</font>, comments, operators, and punctuation marks in <font color=blue>''roman''</font>, with program text in <font color=blue>blue</font> as in the present article to distinguish it from explanatory text.
The specification of Eiffel includes guidelines for displaying software texts in typeset formats: keywords in bold, user-defined identifiers and constants are shown in ''italics'', comments, operators, and punctuation marks in ''roman'', with program text in blue as in the present article to distinguish it from explanatory text.


===Basic instructions===
===Basic instructions===

Revision as of 03:06, 20 August 2006

Eiffel
Paradigmobject-oriented
Designed byBertrand Meyer
DeveloperBertrand Meyer & Eiffel Software
First appeared1986
Stable release
4.2 / Feb 6, 1998
Typing disciplinestatic typing, strong typing
Major implementations
EiffelStudio, SmartEiffel, Visual Eiffel
Influenced by
Ada, Simula, Z
Influenced
Ruby, Sather

Eiffel is an ISO-standardized object-oriented programming language and design methodology intended for the production of quality software with a particular emphasis on extendibility, reusability, reliability and programmer productivity.

With roots going back to 1985, Eiffel is a mature language with development environments available from multiple suppliers. Although less well known than some other object-oriented approaches, Eiffel is used by large projects in various industries (finance, aerospace, health care, games and others) as well as for teaching programming in academia.

The language design is closely connected with the method, based on a set of principles: Design by contract, Command-query separation, Uniform access principle, Single choice principle, Open-closed principle, Option-Operand separation and others.


Many concepts initially introduced by Eiffel have later found their way into other languages such as Java and C#, and Eiffel continues to provide innovative language design ideas, in particular through the ECMA/ISO standardization process.

Overview

Key characteristics of the language, explained in more detail below, include:

  • Mechanisms supporting Design by contract (routine pre- and postconditions, class invariants), tightly integrated with the inheritance mechanism and other language constructs.
  • Object-oriented program structure; classes are the basic decomposition unit.
  • Static typing.
  • Support for automatic memory management, typically implemented by garbage collection.
  • Central role of inheritance including multiple inheritance and mechanisms to make it safe (renaming, redefinition, "select", non-conforming inheritance).
  • A uniform type system handling both value and reference semantics, where all types including basic types such as INTEGER are based on classes.
  • Genericity, constrained and unconstrained.
  • "Agents" (objects wrapping computations, closely connected with closures and lambda calculus.
  • "Once" routines (evaluated only the first time around), for object sharing and decentralized initialization.
  • Keyword-based syntax ALGOL/Pascal tradition but separator-free (semicolon is optional); operator syntax available for routines.

Design goals

The Eiffel language aims to promote clear and elegant programming. Eiffel emphasizes declarative statements over procedural code, and eliminates the need for bookkeeping instructions.

Eiffel shuns coding tricks or coding techniques intended as optimization hints to the compiler. The aim is not only to make the code more readable, but also to allow programmers to concentrate on the important aspects of a program without getting bogged down in implementation details. Eiffel's simplicity is intended to promote simple, extendible, reusable and reliable answers to computing problems. Compilers provide extensive optimization techniques such as automatic inlining which remove part of the burden of optimization from the programmer, with the aim of producing extremely efficient code comparable to e.g. C++.

Design by Contract in Eiffel

Other language mechanisms

Overall structure

An Eiffel "system" (or "program") is a collection of classes. The class is the major unit of decomposition.


At the level above classes: there is a notion of "cluster". A cluster is essentially a group of classes, and possibly subclusters since clusters can be nested. But there is no language construct for "cluster"; this is an organizational tool left to the environment. Typically (but again this is not prescribed):

  • Each class will be in a separate file (standard convention: x.e for the file name if the class is called X).
  • Each cluster will be in a directory (folder) containing such class files; subclusters are in subdirectories.

At the level below classes: a class contains features (roughly corresponding to "members" in e.g. C++), a class invariant, and some other properties such as a "notes" section for documentation.

Any system must have a class designated as "root", and one of its creation procedures designated as "root procedure". Executing the system consists of creating an instance of the root class and executing its root procedure. (Of course this generally creates new objects, calls new features etc.)

Features, commands, queries

The primary characteristic of a class is that it contains a set of features. As a class represents a set of run-time objects (its instances), a feature is an operation on these objects. Operations are of two kinds:

  • Queries, which give information about an instance.
  • Commands, which modify an instance.

This distinction is important to the Eiffel method. In particular:

  • Uniform Access Principle: from the outside, whether a query is an attribute (field in each object) or a function (algorithm) should not make any difference. For example a_vehicle.speed could be an attribute, accessed from the object's representation; or it could be computed by a function that divides distance by time. The notation is the same in both cases, so that it's easy to change representation without affecting the rest of the software.
  • Command-Query Separation Principle: Queries must not modify the instance. This is not a language rule but a methodological principle. So in good Eiffel style one does not find "get" function that change something and return a result; instead there are commands (procedures) to change objects, and queries to obtain information about the object, resulting from preceding changes.

Feature names and no-overloading

An important property of Eiffel is that a class is fundamentally a mapping from feature names to features. More plainly said this means that one name, within one class, means one thing. This keeps things simple and in particular is what makes the multiple inheritance mechanism possible (see below).

Names can, of course, be reused in different classes, but in a given class if you need another feature you'll have to invent another name. This is really no limitation since the conventional kinds of overloading are, in an object-oriented perspective, applied to different classes. For example if you want to have several versions of "+":


  a + b for a, b: INTEGER
  a + b for a, b: REAL
  a + b for a, b: VECTOR [INTEGER]

then in Eiffel it simply means that the three classes involved each have a feature

  plus alias "+" (other: XXX): XXX

where XXX is the given class (INTEGER, REAL, VECTOR [G]). All the usual forms of operator overloading are thus supported; in fact the mechanism is quite extensive since (unlike in most languages) there is considerable freedom in making up new operators, as may be needed in scientific and engineering applications. What is not possible is the kind of argument overloading where a given class has both a feature f (x: X) and another f (y: Y) with the same names. Meyer has argued [1] that such overloading is useless, damages readability, and complicates the language mechanism needlessly.

Genericity

Classes can be generic, to express that they are parameterized by types. Generic parameters appear in square brackets:

  class LIST [G] ...

G is known as a "formal generic parameter". (Eiffel reserves "argument" for routines, and uses "parameter" only for generic classes.) With such a declaration G represents within the class an arbitrary type; so a function can return a value of type G, and a routine can take an argument of that type:

  item: G do ... end
  put (x: G) do ... end

The LIST [INTEGER] and LIST [WORD] are "generic derivations" of this class. Permitted combinations(with n: INTEGER, w: WORD, il: LIST [INTEGER], wl: LIST [WORD]) are

  n := il.item
  wl.put (w)

INTEGER resp. WORD are the "actual generic parameters" in these generic derivations.

It is also possible to have constrained formal parameters, for which the actual parameter must inherit from a given class, the "constraint". For example in

 class HASH_TABLE [G, KEY -> HASHABLE]

a derivation HASH_TABLE [INTEGER, STRING] is valid only if STRING inherits from HASHABLE (as it it indeed does in typical Eiffel libraries). Within the class, having KEY constrained by HASHABLE means that for x: KEY it is possible to apply to x all the features of HASHABLE, as in x.hash_code.

Inheritance basics

Multiple and repeated inheritance

Renaming

Tuples

Agents

Once routines

Conversions

Operator and bracket syntax

Lexical and syntax properties

Eiffel is not case-sensitive. The tokens MaKe, make, and MAKE all refer to the same identifier. Style standards, however, prescribe the use of all-capitals for class names, all-lower-case for feature names, and initial capitals for constants. The recommended style also suggests underscore to separate components of a multi-word identifier, as in average_temperature.

Eiffel's syntax can be parsed without requiring end-of-instruction markers. The use of semicolons as instruction terminators or as instruction separators is left to the discretion of the programmer. Putting a semicolon in or leaving one out makes no difference, except in the unusual case of an instruction starting with a left parenthesis. Most Eiffel programmers choose to omit semicolons except when putting multiple statements on a line.

In contrast to most curly bracket programming languages, Eiffel makes a clear distinction between expressions and instructions. This is in line with the Command-Query Separation principle of the Eiffel method.

The specification of Eiffel includes guidelines for displaying software texts in typeset formats: keywords in bold, user-defined identifiers and constants are shown in italics, comments, operators, and punctuation marks in roman, with program text in blue as in the present article to distinguish it from explanatory text.

Basic instructions

Eiffel has only six basic executable instructions:

  • assignment
  • object creation
  • routine call
  • conditional
  • iteration
  • choice (case)

Unlike many object-oriented languages, but like Smalltalk, Eiffel does not permit an assignment into fields of other objects, as this violates the principles of information hiding and data abstraction. The assignment instruction can only change the value of a field of the current object, or a local variable of the current routine. All changes to other objects must be accomplished by calls to features of that object.

The loop instruction includes a from clause that takes care of loop initialization. The programmer must express the stepping as part of the loop. For example:

  from i := 0 until i >= 10 loop
     my_array.put (0, i)
     i := i + 1
  end

The example above also illustrates that Eiffel treats arrays simply as instances of the class ARRAY, providing access in the form of routine calls, in line with object-oriented ideas. Eiffel compilers optimize this access.

Eiffel's control structures closely follow the principles of structured programming; every block is one-entry-one exit.

Non-object-oriented operations

Eiffel is a purely object-oriented language but provides an open architecture for interfacing with "external" software in any other programming language. It is possible for example to program machine- and operating-system level operations in C. Eiffel provides a straightforward interface to C routines, including allowing for straight C calls within Eiffel code, and "inline C" (writing the body of an Eiffel routine in C, typically for short machine-level operations. Although there is no direct connection between Eiffel and C, three of the four Eiffel compilers output C source code as an intermediate language, to submit to a C compiler, for optimizing and portability. On .NET, the EiffelStudio compiler directly generates CIL (Common Intermediate Language) code for the .NET virtual machine. The SmartEiffel compiler can also output Java bytecode.

Background

Eiffel was originally developed by Eiffel Software, a company founded by Bertrand Meyer (originally called Interactive Software Engineering Inc. or ISE). Eiffel closely follows Dr. Meyer's work in Object Oriented Software Construction, Second Edition. Eiffel differs from most popular languages in several ways.

The goal of the language, libraries, and programing methods is to create reliable, reusable software modules. It supports multiple inheritance, genericity, polymorphism, encapsulation, type-safe conversions, and parameter covariance. Its most important contribution to software engineering is Design by contract (DbC), in which assertions, preconditions, postconditions, and class invariants are used to assist in assuring program correctness without sacrificing efficiency.

Eiffel also offers multiple class inheritance. Many people (such as the designers of Java) have objections to multiple inheritance. The Eiffel implementation of multiple inheritance, in the opinion of its supporters, successfully meets these objections.

Eiffel's design is closely based on Object-Oriented Programming (OOP) theory, with less influence from other paradigms or support for legacy code. The language has formal support for abstract data types. In accordance with Self Documentation, a software text should be able to reproduce its design documentation from the text itself. Eiffel accomplishes this by using a formalized implementation of the Abstract Data Type.

EiffelStudio, an integrated development environment for Eiffel available under both an open source and a commercial licenses, offers an object-oriented environment for software engineering, using some innovative user-interface techniques such as Pick-And-Drop. There are two alternative, also open source implementations, SmartEiffel - the GNU implementation, based on an older version of the language, and Visual Eiffel, which provides a more "traditional" interface. So does EiffelEnvision, a plugin for Microsoft Visual Studio which allows users to edit, compile, and debug Eiffel apps from within the Microsoft Visual Studio IDE. EiffelStudio and EiffelEnvision are only free for non-commercial use, though.

Originally, the language Sather was based on Eiffel, but it has diverged, and now includes several functional programming features.

Specifications and standards

The Eiffel language definition is an international standard of ISO, the International Standards Organization. The standard was developed by ECMA International and its first version approved by ECMA on 21 June 2005 as ECMA standard 367, Eiffel: Analysis, Design and Implementation Language. The second edition was adopted by ECMA in June 2006 and in the same month by ISO. Its text can be found, and used free of charge, here on the ECMA site. The ISO version, standard ISO/IEC DIS 25436, has different formating but its text is identical.

Eiffel Software and Gobo have committed to implementing the standard; Eiffel Software's EiffelStudio 5.7 implements some of the major new mechanisms, in particular inline agents, assigner commands, bracket notation. The SmartEiffel team has turned away from this standard to create its own version of the language, which they believe to be closer to the original style of Eiffel. Object Tools has not to date expressed a position.

The standard cites the following as earlier Eiffel Language specifications:

  • Bertrand Meyer: Eiffel: The Language, Prentice Hall, second printing, 1992 (first printing: 1991)
  • Bertrand Meyer: Standard Eiffel (revision of preceding entry), ongoing, 1997-present, at Bertrand Meyer's ETL3 page, and
  • Bertrand Meyer: Object-Oriented Software Construction, Prentice Hall: first edition, 1988; second edition, 1997.

The ETL3 page requires a password for access which can be found at Bertrand Meyer's Home Page under Work in progress

Differences between SmartEiffel and other implementations

  • SmartEiffel is currently unable to compile the open-source EiffelBase library from Eiffel Software.
  • SmartEiffel is case-sensitive.

A "Hello World" class

class
HELLO_WORLD
create
   make
feature
make is
do
io.put_string ("Hello, world!")
io.put_new_line
end
end

References

  1. ^ Bertrand Meyer: Overloading vs Object Technology, in Journal of Object-Oriented Programming (JOOP), vol. 14, no. 4, October-November 2001, available online
  • Object-Oriented Software Construction, Second Edition, by Bertrand Meyer, Prentice Hall, 1997, ISBN 0-13-629155-4 (see its Wikipedia article); contains a detailed treatment of the concepts and theory of object technology, which led to the design of Eiffel. Available in several languages.

See also