|
Article on other languages:
|
Eiffel is an ISO-standardized, object-oriented programming language designed to enable programmers to efficiently develop extensible, reusable, reliable software. Eiffel is used in academia as a language for teaching computer-programming principles. Eiffel is used in the finance, aerospace, health-care, video-gaming, and other industries as a development platform. Since 1985, many suppliers have developed Eiffel programming environments. The Eiffel language's design is closely connected with the Eiffel programming method. Both are based on a set of principles, including design by contract, command-query separation, uniform-access principle, single-choice principle, open-closed principle, and option-operand separation. Many concepts initially introduced by Eiffel have later found their way into Java, C#, and other languages. New language-design ideas, particularly through the ECMA/ISO standardization process, continue to be incorporated into the Eiffel language. CharacteristicsThe key characteristics of the Eiffel language include:
Design goalsEiffel emphasizes declarative statements over procedural code and attempts to eliminate 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, extensible, reusable, and reliable answers to computing problems. Compilers for computer programs written in Eiffel provide extensive optimization techniques, such as automatic in-lining, that relieve the programmer of part of the optimization burden while producing code whose efficiency is comparable to that of code written in C++. BackgroundEiffel was originally developed by Eiffel Software, a company originally called Interactive Software Engineering Inc. (ISE) founded by Bertrand Meyer. Object-Oriented Software Construction contains a detailed treatment of the concepts and theory of the object technology that led to Eiffel's design.[1] The design goal behind the Eiffel language, libraries, and programming methods is to enable programmers to create reliable, reusable software modules. Eiffel supports multiple inheritance, genericity, polymorphism, encapsulation, type-safe conversions, and parameter covariance. Eiffel's most important contribution to software engineering is design by contract (DbC), in which assertions, preconditions, postconditions, and class invariants are employed to help ensure program correctness without sacrificing efficiency. Eiffel's design is based on object-oriented programming theory, with only minor influence of other paradigms or concern for support of legacy code. Eiffel formally supports abstract data types. Under Eiffel's design, a software text should be able to reproduce its design documentation from the text itself, using a formalized implementation of the "Abstract Data Type". Implementations and environmentsEiffelStudio is an integrated development environment available under either an open source or a commercial license. It offers an object-oriented environment for software engineering. EiffelEnvision is a plug-in for Microsoft Visual Studio that allows users to edit, compile, and debug Eiffel projects from within the Microsoft Visual Studio IDE. EiffelStudio and EiffelEnvision are free for non-commercial use. Three other open source implementations are available: Gobo Eiffel, SmartEiffel—the GNU implementation, based on an older version of the language—and Visual Eiffel. Several other programming languages incorporate elements first introduced in Eiffel. Sather, for example, was originally based on Eiffel but has since diverged, and now includes several functional programming features. The interactive-teaching language Blue, forerunner of BlueJ, is also Eiffel-based. The Apple Media Tool includes an Eiffel-based Apple Media Language. Specifications and standardsThe Eiffel language definition is an international standard of the ISO. The standard was developed by ECMA International, which first approved the standard on 21 June 2005 as ECMA standard 367, Eiffel: Analysis, Design and Implementation Language. In June 2006, ECMA and ISO adopted the second version. In November 2006, ISO first published that version. The standard can be found and used free of charge on the ECMA site.[2] The ISO version[3] is identical in all respects except formatting. Eiffel Software and Eiffel-library-developer Gobo have committed to implementing the standard; Eiffel Software's EiffelStudio 6.1 implements some of the major new mechanisms—in particular, inline agents, assigner commands, bracket notation, non-conforming inheritance, and attached types. 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 disclosed whether future versions of its Eiffel compiler will comply with the standard. The standard cites the following, predecessor Eiffel-language specifications:
Syntax and semanticsOverall structureAn Eiffel "system" or "program" is a collection of classes. Above the level of classes, Eiffel defines cluster, which are essentially a group of classes, and possibly of subclusters (nested clusters). Clusters are not a syntactic language construct, but rather a standard organizational convention. Typically an Eiffel application will be organized with each class in a separate file, and each cluster in a directory containing class files. In this organization, subclusters are subdirectories. For example, under standard organizational and casing conventions, A class contains features, which are similar to "members", "attributes" or "methods" in other object-oriented programming languages. A class also defines its invariants, and contains other properties, such as a "notes" section for documentation. Eiffel's standard data types, such as Every system must have a class designated as "root", with one of its creation procedures designated as "root procedure". Executing a system consists of creating an instance of the root class and executing its root procedure. Generally, doing so creates new objects, calls new features, and so on. Eiffel has six basic executable instructions: assignment; object creation; routine call; conditional; iteration; and choice. Eiffel's control structures are strict in enforcing structured programming: every block has exactly one entry and exactly one exit. ScopingUnlike many object-oriented languages, but like Smalltalk, Eiffel does not permit any assignment into fields of objects, except within the features of an object. Eiffel emphasizes information hiding and data abstraction, by requiring formal interfaces to data mutation. To put it in the language of other object-oriented programming languages, all Eiffel fields are "private", and "setters" are needed to modify values. An upshot of this is that "setters" can, and normally do, implement the invariants Eiffel provides syntax for. "Hello, world!"A programming language's look and feel is often conveyed using a "Hello, world!" program. Such a program written in Eiffel might be: class HELLO_WORLD create make feature make do print ("Hello, world!%N") end end Design by ContractThe concept of design by contract is central to Eiffel. The mechanisms are tightly integrated with the language. Contracts guide redefinition of features in inheritance.
In addition, the language supports a "check instruction" (a kind of "assert") and loop invariants. Features, commands, queriesThe primary characteristic of a class is that it contains a set of features. As a class represents a set of run-time objects, or "instances", a feature is an operation on these objects. There are two kinds of features: queries and commands. A query provides information about an instance. A command modifies an instance. The command-query distinction is important to the Eiffel method. In particular:
OverloadingEiffel does not allow argument overloading. Each feature name within a class always maps to a specific feature within the class. One name, within one class, means one thing. This design choice helps the readability of classes, by avoiding a cause of ambiguity about which routine will be invoked by a call. It also simplifies the language mechanism; in particular, this is what makes Eiffel's multiple inheritance mechanism possible.[4] Names can, of course, be reused in different classes. For example the "+" operator is defined in several classes: INTEGER, REAL, STRING, etc. GenericityClasses 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 n := il.item wl.put (w)
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 Inheritance basicsTo inherit from one or more others, a class will include an class C inherit A B -- ... Rest of class declaration ... The class may redefine (override) some or all of the inherited features. This must be explicitly announced at the beginning of the class through a class C inherit A redefine f, g, h end B redefine u, v end Deferred classes and featuresClasses may be defined with Deferred classes play some of the same role as interfaces in languages such as Java, though many object-oriented programming theorists believe interfaces are themselves largely an answer to Java's lack of multiple inheritance (which Eiffel has). RenamingA class that inherits from one or more others gets all its features, by default under their original names. It may, however, change their names through TuplesTuples types may be viewed as a simple form of class, providing only attributes and the corresponding "setter" procedure. A typical tuple type reads TUPLE [name: STRING; weight: REAL; date: DATE] and could be use to describe a simple notion of birth record if a class is not needed. An instance of such a tuple is simply a sequence of values with the given types, given in brackets, such as ["Brigitte", 3.5, Last_night] Components of such a tuple can be accessed as if the tuple tags were attributes of a class, for example if Thanks to the notion of assigner command (see below), dot notation can also be used to assign components of such a tuple, as in t.weight := t.weight + 0.5 The tuple tags are optional, so that it is also possible to write a tuple type as The precise specification of e.g. AgentsEiffel's "agent" mechanism wraps operations into objects. This mechanism can be used for iteration, event-driven programming, and other contexts in which it is useful to pass operations around the program structure. Other programming languages, especially ones that emphasize functional programming, allow a similar pattern using continuations, closures, or generators; Eiffel's agents emphasize the language's object-oriented paradigm, and use a syntax and semantics similar to code blocks in Smalltalk and Ruby. For example, to execute the my_list.do_all (agent my_action) To execute my_list.do_if (agent my_action, agent my_condition) In these examples, a.call ([x]) will call the original routine with the argument It is possible to keep some arguments to an agent open and make others closed. The open arguments are passed as arguments to my_list.do_all (agent action2 (?, y)) iterates The distinction between open and closed operands (operands = arguments + target) corresponds to the distinction between bound and free variables in lambda calculus. An agent expression such as The agent mechanism has been recently generalized to allow defining an agent without reference to an existing routine (such as my_list.do_all (agent (s: STRING) require not_void: s /= Void do s.append_character (',') ensure appended: s.count = old s.count + 1 end) The inline agent passed here can have all the trappings of a normal routine, including precondition, postcondition, rescue clause (not used here), and a full signature. This avoids defining routines when all that's needed is a computation to be wrapped in an agent. This is useful in particular for contracts, as in an invariant clause that expresses that all elements of a list are positive: my_list.for_all (agent (x: INTEGER): BOOLEAN do Result := (x > 0) end) The current agent mechanism leaves a possibility of run-time type error (if a routine with n arguments is passed to an agent expecting m arguments with m < n). This can be avoided by a run-time check through the precondition Once routinesA routine's result can be cached using the
shared_object: SOME_TYPE
once
create Result.make (args)
-- This creates the object and returns a reference to it through `Result'.
end
The returned object— Often "once routines" perform a required initialization: multiple calls to a libraries can include a call to the initialization procedure, but only the first such call will perform the required actions. Using this pattern initialization can be decentralized, avoiding the need for a special initialization module. "Once routines" are similar in purpose and effect to the singleton pattern in many programming languages, and to the Borg pattern used in Python. The ECMA specification allows variants of "once" (qualified by a keyword in parentheses, e.g. ConversionsEiffel provides a mechanism to allow conversions between various types. The mechanisms coexists with inheritance and complements it. To avoid any confusion between the two mechanisms, the design enforces the following principle:
For example The conversion mechanism simply generalizes the ad hoc conversion rules (such as indeed between my_string := my_date as a shortcut for using an explicit object creation with a conversion procedure: create my_string.make_from_date (my_date) To make the first form possible as a synonym for the second, it suffices to list the creation procedure (constructor) As another example, if there is such a conversion procedure listed from Bastille_day := [14, "July", 1789] Exception handlingException handling in Eiffel is based on the principles of design by contract. For example, an exception occurs when a routine's caller fails to satisfy a precondition, or when a routine cannot ensure a promised postcondition. In Eiffel, exception handling is not used for control flow or to correct data-input mistakes. An Eiffel exception handler is defined using the rescue keyword. Within the rescue section, the retry keyword executes the routine again. For example, the following routine tracks the number of attempts at executing the routine, and only retries a certain number of times: connect_to_server (server: SOCKET) -- Connect to a server or give up after 10 attempts. require server /= Void and then server.address /= Void local attempts: INTEGER do server.connect ensure connected: server.is_connected rescue if attempts < 10 then attempts := attempts + 1 retry end end This example is arguably flawed for anything but the simplest programs, however, because connection failure is to be expected. For most programs a routine name like attempt_connecting_to_server would be better, and the postcondition would not promise a connection, leaving it up to the caller to take appropriate steps if the connection was not opened. ConcurrencyA number of networking and threading libraries are available, such as EiffelNet and EiffelThreads. A concurrency model for Eiffel, based on the concepts of design by contract, is SCOOP (software), or Simple Concurrent Object-Oriented Programming, not yet part of the official language definition but available as an add-on from ETH Zurich. Operator and bracket syntax, assigner commandsEiffel's view of computation is completely object-oriented in the sense that every operation is relative to an object, the "target". So for example an addition [1] a + b is conceptually understood as if it were a function call [2] a.plus (b) with target Of course [1] is the conventional syntax and usually preferred. Operator syntax makes it possible to use either form by declaring the feature (for example in plus alias "+" (other: INTEGER): INTEGER -- ... Normal function declaration... end The range of operators that can be used as "alias" is quite broad; they include predefined operators such as "+" but also "free operators" made of non-alphanumeric symbols. This makes it possible to design special infix and prefix notations, for example in mathematics and physics applications. Every class may in addition have one function aliased to "[]", the "bracket" operator, allowing the notation number := phone_book ["JILL SMITH"] "Assigner commands" are a companion mechanism designed in the same spirit of allowing well-established, convenient notation reinterpreted in the framework of object-oriented programming. Assigner commands allow assignment-like syntax to call "setter" procedures. An assignment proper can never be of the form item alias "[]" (key: STRING): ELEMENT [3] -- The element of key `key'. -- ("Getter" query) do ... end put (e: ELEMENT; key: STRING) -- Insert the element `e', associating it with the key `key'. -- ("Setter" command) do ... end Then to insert an element you have to use an explicit call to the setter command: [4] phone_book.put (New_person, "JILL SMITH") It is possible to write this equivalently as [5] phone_book ["JILL SMITH"] := New_person (in the same way that item alias "[]" (key: STRING): ELEMENT assign put This declares note: The argument list of a's assigner is constrained to be: (a's return type;all of a's argument list...) Lexical and syntax propertiesEiffel is not case-sensitive. The tokens Comments are introduced by The semicolon, as instruction separator, is optional. Most of the time the semicolon is just omitted, except to separate multiple instructions on a line. This results in less clutter on the program page. There is no nesting of feature and class declarations. As a result the structure of an Eiffel class is simple: some class-level clauses (inheritance, invariant) and a succession of feature declarations, all at the same level. It is customary to group features into separate "feature clauses" for more readability, with a standard set of basic feature tags appearing in a standard order, for example: class HASH_TABLE [ELEMENT, KEY -> HASHABLE] inherit TABLE [ELEMENT] feature -- Initialization -- ... Declarations of initialization commands (creation procedures/constructors) ... feature -- Access -- ... Declarations of non-boolean queries on the object state, e.g. item ... feature -- Status report -- ... Declarations of boolean queries on the object state, e.g. is_empty ... feature -- Element change -- ... Declarations of commands that change the structure, e.g. put ... -- etc. end 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. Style conventionsMuch of the documentation of Eiffel uses distinctive style conventions, designed to enforce a consistent look-and-feel. Some of these conventions apply to the code format itself, and others to the standard typographic rendering of Eiffel code in formats and publications where these conventions are possible. While the language is case-insensitive, the style standards prescribe the use of all-capitals for class names ( The specification of Eiffel includes guidelines for displaying software texts in typeset formats: keywords in bold, user-defined identifiers and constants are shown in
class
HELLO_WORLD
create
make
feature
make
do
io.put_string ("Hello, world!")
io.put_new_line
end
end
Interfaces to other tools and languagesEiffel 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 support for "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, all of the current Eiffel compilers except one (Visual Eiffel) 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. References
External links
|
||||||||||||||||||||||||||||||||
This article is from Wikipedia. All text is available under the terms of the GNU Free Documentation License.
Mercedes Car
This site monitored by SitePinger.net