Previous Table of Contents Next


Nowhere in the software text should we have to specify which processor to use. All we state, through the separate declaration, is that two objects are handled by different processors because this radically affects the system’s semantics. Actual processor assignment can wait until runtime. Nor do we settle too early on the exact nature of processors: A processor can be implemented by a piece of hardware (a computer), but just as well by a task (process) of the operating system, or, on a multithreaded OS, just a thread of such a task. Viewed by the software, “processor” is an abstract concept; you can execute the same concurrent application on widely different architectures (time-sharing on one computer, distributed network with many computers, or threads within one UNIX or Windows task) without any change to its source text. All you change is a concurrency configuration file that specifies the last-minute mapping of abstract processors to physical resources.

We need to specify synchronization constraints. The conventions are straightforward:

  No special mechanism is required for a client to resynchronize with its supplier after a separate call x.f (a) has gone off in parallel. The client waits when and if it needs to: when it requests information on the object through a query call, as in value := x.some_query. This automatic mechanism is called wait by necessity.
  To obtain exclusive access to a separate object O2, it suffices to use the attached entity a as an argument to the corresponding call, as in r (a).
  A routine precondition involving a separate argument such as a causes the client to wait until the precondition holds.
  To guarantee that we can control our software and predict the result (in particular, rest assured that class invariants are maintained), we must allow the processor in charge of an object to execute at most one routine at any given time.
  We may, however, need to interrupt the execution of a routine to let a new, high-priority client take over. This causes an exception so that the spurned client can take the appropriate corrective measures—most likely retrying after a while.

This covers most of the mechanism, which enables us to build the most advanced concurrent and distributed applications through the full extent of Eiffel techniques reviewed in this chapter, from multiple inheritance and behavior classes to static typing, dynamic binding, and design by contract.

9.11.2. Other Developments

As part of the growth of Eiffel usage in large projects and its openness to the rest of the software world, a number of important developments, some already in the form of products, and still others in progress, have recently occurred:

  Development of multithreading libraries (which may be used without the SCOOP extensions of the preceding section for users using sequential Eiffel or in conjunction with SCOOP).
  CORBA interfaces, as a result of a cooperation between ISE and ICL Ltd. and of a multivendor effort leading to a proposed official Eiffel binding for IDL, the Interface Definition Language of CORBA.
  Interfaces to Microsoft’s OLE 2 and ActiveX.
  Interfaces to relational and object-oriented databases.
  Libraries or reusable components in many different areas (such as ISE’s EiffelMath for scientific and financial applications).
  Java and Java bytecode generation, Java interfaces.
  Interfaces to many other industry-standard products.

9.12. Eiffel History

I designed Eiffel on September 23, 1985. It was initially intended as an internal tool for the newly created ISE. The first internal implementation was ready in mid-1986.

The main influences on the design of Eiffel have been

  The object-oriented concepts introduced by Simula 67, which I was able to practice starting at the end of 1973.
  Work on formal specification, in particular Abrial’s original version of the Z specification language, with which I had been associated (and which I documented in a 1978 book).
  Work on abstract data types by Liskov, Zilles, Guttag, and me.
  The Algol 60/Algol W/Pascal/Ada line of programming languages.
  Work on program proving and axiomatic semantics (Floyd, Hoare, and Dijkstra).
  Modern concepts of software engineering, in particular the work on software quality.

A presentation at the first OOPSLA conference (Object-Oriented Programming, Systems, Languages, and Applications, Portland, September 1986) revealed that many of the concepts and their implementation were ahead of the rest of the industry as well as of academic research and led to the transformation of the compiler into a commercial product, which started to be sold to companies and universities worldwide in December 1986. Version 2 was introduced in 1988.

The book Object-Oriented Software Construction (Meyer, 1988, 1997) enjoyed a large success and introduced Eiffel to a broader community.

In 1990, ISE decided to relinquish control of the Eiffel language and kernel library to an independent organization, NICE (the Nonprofit International Consortium for Eiffel), which was incorporated in the same year. This enabled the development of compilers and tools from other sources and the birth of an Eiffel industry.

At the same time, a general cleanup of the language was undertaken, which led to a number of simplifications and a few extensions. These changes did not, however, affect the essential concepts and techniques of the language and method; Eiffel has been remarkably stable and remains close today to the original 1985 design. The language reference, Eiffel: The Language (Meyer, 1992), the result of this revision, was published in 1991 and revised the following year. Under the control of NICE, a few further adaptations are planned, meant to make the practice of Eiffel usage more pleasurable without causing any upward-compatibility problems or introducing any major conceptual change.


Previous Table of Contents Next