Smalltalk (that is Smalltalk-80 of ParcPlace Systems) comes with a large collection of general purpose and graphics programming classes, that are identical for both MS-DOS and Unix platforms. Also Eiffel comes with a standard collection of well-documented libraries containing common data structures, container classes and classes for graphics programming. For both Smalltalk and Eiffel, the accompanying classes may almost be considered to be part of the language definition, in the sense that they provide a standard means to solve particular problems.
In contrast, for C++ there is almost no standard library support (except for IO stream classes). Even worse, the various C++ compiler vendors disagree considerably in what functionality the standard class libraries of C++ must offer. Fortunately, however, there is an increasingly large number of third party libraries (commercially and non-commercially) available. The burden of choosing the appropriate libraries is, however, placed on the shoulders of a user or a company, which has the advantage that a more optimal solution may be obtained than possible within the confines of standard libraries.
Java, on the other hand, offers an overwhelming amount of APIs, including a Reflection API, for meta programming, APIs for networking, communication, and APIs for multimedia and 3D. Perhaps the greatest benefit of Java is the effort put into the standardization of these APIs.
Of the object-oriented programming languages we consider, Smalltalk definitely offers the most comprehensive programming environment (including editors, browsers and debuggers). Eiffel comes with a number of additional tools (such as a graphical browser, and a program documentation tool) to support program development (and maintenance).
In contrast, C++ usually comes with nothing at all. However, increasingly many tools (including browsers and debuggers) have become available.
For Java there are a number of IDEs (Integrated Development Environments) available, most of which run only on the PC platform.
The issue of producing documentation from C++ is still open. A number of tools exist (including a WEB-like system for C++ and a tool to produce manual pages from C++ header files) but no standard has yet emerged. Moreover, some people truly dislike the terseness of C/C++. Personally, I prefer the C/C++ syntax above the syntactical conventions of both Eiffel and Smalltalk, provided that it is used in a disciplined fashion.
Java programs may be documented using javadoc. The javadoc program may be regarded as the standard C++ has been waiting for, in vain.
An important feature of Eiffel is that it supports assertions that may be validated at runtime. In combinations with exceptions, this provides a powerful feature for the development of reliable programs.
At the price of some additional coding (for example, to save the current state to enable the use of the old value), such assertions may be expressed by using the assert macros provided for C++.
In defense of C++, it is important to acknowledge that C++ offers adequate protection mechanisms to shield classes derived by inheritance from the implementation details of their ancestor classes. Neither Smalltalk nor Eiffel offer such protection.
Java was introduced as a more reliable variant of C++. Java's reliability comes partly from the shielded environment offered by the Java virtual machine, and partly from the absence of pointers and the availability of built-in garbage collection. Practical experience shows that for the average student/programmer Java is indeed substantially less error-prone than C++.
As far as the assertion mechanism offered by Eiffel
The Java language offers only single (code) inheritance, but allows for multiple interface inheritance. The realization of (multiple) interfaces seems to be a fairly good substitute for multiple (implementation) inheritance.
The compilation of Eiffel programs can result in programs having adequate execution speed. However, in Eiffel dynamic binding takes place in principle for all methods. Yet a clever compiler can significantly reduce the number of indirections needed to execute a method.
In contrast to C++, in Eiffel all objects are created on the heap. The garbage collection needed to remove these objects may affect the execution speed of programs.
C++ has been designed with efficiency in mind. For instance, the availability of inline functions, and the possibility to allocate objects on the runtime stack (instead of on the heap), and the possibility to declare friend functions and classes that have direct access to the private instance variables of a class allow the programmer to squeeze out the last drop of efficiency. However, as a drawback, when higher level functionality is needed (as in automatic garbage collection) it must be explicitly programmed, and a similar price as when the functionality would have been provided by the system has to be paid. The only difference is that the programmer has a choice.
At the time of writing there does not exist a truly efficient implementation of the Java language. Significant improvements may be expected from the JIT (Just In Time) compilers that produce native code dynamically, employing techniques as originally developed for the Self language, discussed in section Self.
Eiffel contains few language elements that extend beyond object-oriented programming. In particular, Eiffel does not allow for overloading method names (according to signature) within a class. This may lead to unnecessarily elaborate method names. (The new version of Eiffel (Eiffel-3) does allow for overloading method names.)
Without doubt, C++ is generally regarded as a highly complex language. In particular, the rules governing the overloading of operators and functions are quite complicated. The confusion even extends to the various compiler suppliers, which is one of the reasons why C++ is still barely portable. Somewhat unfortunately, the rules for overloading and type conversion for C++ have to a large extent been determined by the need to remain compatible with C. Even experienced programmers need occasionally to experiment to find out what will happen.
Java is certainly less complex than C++. For example, it offers no templates, no operator overloading and no type coercion operators. However, although Java is apparently easier to use, it is far less elegant than C++ when it comes to creating user-defined types. Class interfaces in Java are usually much more verbose than similar interfaces in C++. And, due to the absence of templates, type casts are necessary in many places. On the other hand, casts in Java are type safe.
draft version 0.1 (15/7/2001)