|
|
Language Design Before Our Eyes: The Birth and Evolution of Java
Introduction:
This paper will use Sun's Java programming language as an example to study the design of modern programming languages. Java is a good example because it is very new, and most if not all of us in professional software development saw the introduction of Java. Based on the published purpose of the language, we will talk about how some of the design decisions were made based on pragmatic issues, and how some features have been well and ill received by developers. The paper will conclude by determining to what extent the current version of Java has met the language's original design goals, whether pragmatic decisions made in the design phase were good ones, and how developer reaction may impact the ongoing evolution of the language.
Java is an extraordinarily interesting programming language to study because it is so young. That means two things: 1. most of us were in the profession of software engineering when Java was released, so we've seen the birth and evolution of the language; 2. it is a language that continues to change and mature. These two characteristics make it ideal for studying how language designers make decisions regarding high level language design when creating a new programming language. Java specifically was an attempt to solve some of the problems that developers encounter when using another popular programming language, C++. As a result, there are many comparisons and contrasts between Java and C++, and many of Java's design considerations were driven by then-current thoughts on the design of C++. (Anonymous, Gosling)
Java is a proprietary language designed by Sun Microsystems. Unlike other popular languages like C and C++, Java is not standardized by an international body like ANSI or ISO. For this reason, much of the design documentation available for other languages is not available for Java. What we do have are the language environment white paper titled "The Java Language: An Overview", the virtual machine specification, and the language specification. The decision not to release Java to a standardization committee is in itself a design consideration. Although there are advantages, the choice to go with international standardization is not a perfect one. One problem that Java has avoided include an extremely long standardization process, leading to a quicker time to market. The simple fact is that many of the design decisions made in Java were business based; Java, although it is distributed for free, is a commercial product. (Eckles et al)
Contrary to popular belief, Java was not a language originally intended to be an "internet" language. Rather, its original purpose was to be an embedded language in consumer electronics. In "The Java Language: An Overview", the author states the buzz-word rich definition of Java: "A simple, object-oriented, network-savvy, interpreted, robust, secure, architecture neutral, portable, high-performance, multithreaded, dynamic language." While that's quite a broad-based definition, it is a good starting point for examining specific design decisions. (Anonymous)
By simple, the language designers meant that they wanted developers to have the ability to easily program with the language without esoteric training and using current industry standard practices. For this reason, the syntax of the language borrows very heavily from C++. This aids comprehension, but at the same time Java was able to exclude rarely used, poorly understood, and confusing features of C++; examples include operator overloading, multiple inheritance, and extensive automatic coercions. While few have missed operator overloading, and the removal of many coercions clearly improves the robustness of the language, many have criticized the lack of multiple inheritance of Java. Multiple inheritance is arguably a fundamental concept of Object Oriented design, and its absence sometimes places an undue burden on programmers who wish to extend a delivered subclass with inherited properties of a custom class. To some degree a work-around exists with Java interfaces, but this is an incomplete solution. The advantage to removing multiple inheritance is a much cleaner object hierarchy that allows developers to much more quickly come up to speed on the delivered library. It also forces developers to more thoroughly think out their class designs, preventing errors early in the development life cycle. (Anonymous, Gosling)
Robustness was of course another goal of the language designers, and several design decisions were made to support this. Most notably, Java is a very strongly typed language. Unlike scripting languages like JavaScriptand Perl that use "scalar" variables with no type or Visual Basic which provides a "variant" type which is presumably similar to a C pointer in implementation but a typeless variable in practice, Java requires that every variable have a type. Also, unlike C and C++, implicit declarations are not allowed; every variable used in a program must be declared before its use (an example of implicit declaration is the common C construct for( int i=0; i
The most famed design goal of Java was to provide a language that is architecture neutral and portable. Java was originally intended for applications on heterogeneous networks, meaning that the programs would run on multiple types of devices. To achieve this, the designers made Java an interpreted language; compiled source files are stored in a common format known as "byte codes" which can be translated directly to machine code via the Java Virtual Machine. This means that the same Java program can be executed on any of many different processors given the presence of the Java Runtime Environment. Another key to Java's portability is that details left up to implementation in other languages are specified by Java. The most obvious example is the specification of the size of language primitives. In C, the size of an integer primitive is determined by the underlying architecture of the target machine. In Java, an integer primitive is always a signed 32 bit number. That means that the same Java program can work on 16, 32, or 64 bit architectures without any recoding or recompilation. Even more advanced features like windowing is abstracted into a platform-independent library which is implemented by the Java Runtime Environment on a number of different systems (Unix, Mac, Windows, etc.).
What allows such low-level details to be left to the implementation is the choice the designers made to make Java a dynamic linking language. This means that the library code is linked to the application code at runtime rather than at compile time. This leads to several benefits: 1. libraries are abstracted and centralized, meaning that Sun can easily distribute changes to the libraries without requiring code changes or recompilation of existing programs; 2. class types can be dynamically discovered at runtime (a feature not available to C++); 3. classes can be loaded dynamically at runtime given only the class name (again, a feature not available to C++). Dynamic linking does, however, have its drawbacks. Because it is so easy to make modifications and additions to the dynamically linked library, the observation has been made that the library "grows forever". Static linking also allows the developer to include only the code needed by the application for distribution. Finally, Tim Tyler points out that the decision to use dynamic linking may have been more business driven that technology driven; because the libraries are dynamically linked, Sun is able to maintain control over the licensing and distribution of the libraries. (Anonymous, Eckles et al)
Conclusion:
As we can see, the decision criteria for design decisions in the creation of a new programming language are not limited just to technical idealism; rather, decisions also take into consideration business, political, and pragmatic criteria. The best example of this is that Java's dynamic linking approach is strongly business-driven even though technical arguments might persuade one that a static linking approach would better serve the language and programmer. One the whole, given the working definition of Java as "A simple, object-oriented, network-savvy, interpreted, robust, secure, architecture neutral, portable, high-performance, multithreaded, dynamic language," it is safe to say that Java has met its design objectives. While "simple" is a relative term, the syntax is not cumbersome and familiar to a very large base of programmers. It does not completely implement object orientation, but it does far better than some of its predecessors and does so in an intelligent manner. It is clearly network-savvy, having become the internet programming language of choice. Its interpreted architecture supports its architecture neutral, portable, and high-performance objectives. Finally, experience has shown that Java is both a robust and secure language. While developers may debate over some of the design decisions made in Java, it appears that given the success of the language that the designers largely made the right choices.
References:
- Anonymous. "The Java Language: An Overview". http://java.sun.com/docs/overviews/java/java-overview-1.html.
- Eckles, James and Tim Tyler, Tilo Körbs, D'Arcy Smith, et al. "looking for resource on Java language design". March 8, 2002. Usenet comp.lang.java.advocacy, 26 articles in thread.
- Gosling, James and Henry McGilton. "The Java Language Environment". May, 1996. http://java.sun.com/docs/white/langenv/Object.doc2.html#2600.
If you have any questions or would like to contact me for any reason, please email me at j.eckles@computer.org.
|