
- •New to the Tenth Edition
- •Preface
- •Acknowledgments
- •About the Author
- •Contents
- •1.1 Reasons for Studying Concepts of Programming Languages
- •1.2 Programming Domains
- •1.3 Language Evaluation Criteria
- •1.4 Influences on Language Design
- •1.5 Language Categories
- •1.6 Language Design Trade-Offs
- •1.7 Implementation Methods
- •1.8 Programming Environments
- •Summary
- •Problem Set
- •2.1 Zuse’s Plankalkül
- •2.2 Pseudocodes
- •2.3 The IBM 704 and Fortran
- •2.4 Functional Programming: LISP
- •2.5 The First Step Toward Sophistication: ALGOL 60
- •2.6 Computerizing Business Records: COBOL
- •2.7 The Beginnings of Timesharing: BASIC
- •2.8 Everything for Everybody: PL/I
- •2.9 Two Early Dynamic Languages: APL and SNOBOL
- •2.10 The Beginnings of Data Abstraction: SIMULA 67
- •2.11 Orthogonal Design: ALGOL 68
- •2.12 Some Early Descendants of the ALGOLs
- •2.13 Programming Based on Logic: Prolog
- •2.14 History’s Largest Design Effort: Ada
- •2.15 Object-Oriented Programming: Smalltalk
- •2.16 Combining Imperative and Object-Oriented Features: C++
- •2.17 An Imperative-Based Object-Oriented Language: Java
- •2.18 Scripting Languages
- •2.19 The Flagship .NET Language: C#
- •2.20 Markup/Programming Hybrid Languages
- •Review Questions
- •Problem Set
- •Programming Exercises
- •3.1 Introduction
- •3.2 The General Problem of Describing Syntax
- •3.3 Formal Methods of Describing Syntax
- •3.4 Attribute Grammars
- •3.5 Describing the Meanings of Programs: Dynamic Semantics
- •Bibliographic Notes
- •Problem Set
- •4.1 Introduction
- •4.2 Lexical Analysis
- •4.3 The Parsing Problem
- •4.4 Recursive-Descent Parsing
- •4.5 Bottom-Up Parsing
- •Summary
- •Review Questions
- •Programming Exercises
- •5.1 Introduction
- •5.2 Names
- •5.3 Variables
- •5.4 The Concept of Binding
- •5.5 Scope
- •5.6 Scope and Lifetime
- •5.7 Referencing Environments
- •5.8 Named Constants
- •Review Questions
- •6.1 Introduction
- •6.2 Primitive Data Types
- •6.3 Character String Types
- •6.4 User-Defined Ordinal Types
- •6.5 Array Types
- •6.6 Associative Arrays
- •6.7 Record Types
- •6.8 Tuple Types
- •6.9 List Types
- •6.10 Union Types
- •6.11 Pointer and Reference Types
- •6.12 Type Checking
- •6.13 Strong Typing
- •6.14 Type Equivalence
- •6.15 Theory and Data Types
- •Bibliographic Notes
- •Programming Exercises
- •7.1 Introduction
- •7.2 Arithmetic Expressions
- •7.3 Overloaded Operators
- •7.4 Type Conversions
- •7.5 Relational and Boolean Expressions
- •7.6 Short-Circuit Evaluation
- •7.7 Assignment Statements
- •7.8 Mixed-Mode Assignment
- •Summary
- •Problem Set
- •Programming Exercises
- •8.1 Introduction
- •8.2 Selection Statements
- •8.3 Iterative Statements
- •8.4 Unconditional Branching
- •8.5 Guarded Commands
- •8.6 Conclusions
- •Programming Exercises
- •9.1 Introduction
- •9.2 Fundamentals of Subprograms
- •9.3 Design Issues for Subprograms
- •9.4 Local Referencing Environments
- •9.5 Parameter-Passing Methods
- •9.6 Parameters That Are Subprograms
- •9.7 Calling Subprograms Indirectly
- •9.8 Overloaded Subprograms
- •9.9 Generic Subprograms
- •9.10 Design Issues for Functions
- •9.11 User-Defined Overloaded Operators
- •9.12 Closures
- •9.13 Coroutines
- •Summary
- •Programming Exercises
- •10.1 The General Semantics of Calls and Returns
- •10.2 Implementing “Simple” Subprograms
- •10.3 Implementing Subprograms with Stack-Dynamic Local Variables
- •10.4 Nested Subprograms
- •10.5 Blocks
- •10.6 Implementing Dynamic Scoping
- •Problem Set
- •Programming Exercises
- •11.1 The Concept of Abstraction
- •11.2 Introduction to Data Abstraction
- •11.3 Design Issues for Abstract Data Types
- •11.4 Language Examples
- •11.5 Parameterized Abstract Data Types
- •11.6 Encapsulation Constructs
- •11.7 Naming Encapsulations
- •Summary
- •Review Questions
- •Programming Exercises
- •12.1 Introduction
- •12.2 Object-Oriented Programming
- •12.3 Design Issues for Object-Oriented Languages
- •12.4 Support for Object-Oriented Programming in Smalltalk
- •12.5 Support for Object-Oriented Programming in C++
- •12.6 Support for Object-Oriented Programming in Objective-C
- •12.7 Support for Object-Oriented Programming in Java
- •12.8 Support for Object-Oriented Programming in C#
- •12.9 Support for Object-Oriented Programming in Ada 95
- •12.10 Support for Object-Oriented Programming in Ruby
- •12.11 Implementation of Object-Oriented Constructs
- •Summary
- •Programming Exercises
- •13.1 Introduction
- •13.2 Introduction to Subprogram-Level Concurrency
- •13.3 Semaphores
- •13.4 Monitors
- •13.5 Message Passing
- •13.6 Ada Support for Concurrency
- •13.7 Java Threads
- •13.8 C# Threads
- •13.9 Concurrency in Functional Languages
- •13.10 Statement-Level Concurrency
- •Summary
- •Review Questions
- •Problem Set
- •14.1 Introduction to Exception Handling
- •14.2 Exception Handling in Ada
- •14.3 Exception Handling in C++
- •14.4 Exception Handling in Java
- •14.5 Introduction to Event Handling
- •14.6 Event Handling with Java
- •14.7 Event Handling in C#
- •Review Questions
- •Problem Set
- •15.1 Introduction
- •15.2 Mathematical Functions
- •15.3 Fundamentals of Functional Programming Languages
- •15.4 The First Functional Programming Language: LISP
- •15.5 An Introduction to Scheme
- •15.6 Common LISP
- •15.8 Haskell
- •15.10 Support for Functional Programming in Primarily Imperative Languages
- •15.11 A Comparison of Functional and Imperative Languages
- •Review Questions
- •Problem Set
- •16.1 Introduction
- •16.2 A Brief Introduction to Predicate Calculus
- •16.3 Predicate Calculus and Proving Theorems
- •16.4 An Overview of Logic Programming
- •16.5 The Origins of Prolog
- •16.6 The Basic Elements of Prolog
- •16.7 Deficiencies of Prolog
- •16.8 Applications of Logic Programming
- •Review Questions
- •Programming Exercises
- •Bibliography
- •Index

2.17 An Imperative-Based Object-Oriented Language: Java |
91 |
2.16.6A Loosely Related Language: Go
The Go programming language is not directly related to C++, although it is C-based. It is in this section in part because it does not deserve its own section and it does not fit elsewhere.
Go was designed by Rob Pike, Ken Thompson, and Robert Griesemer at Google. Thompson is the designer of the predecessor of C, B, as well as the codesigner with Dennis Ritchie of UNIX. He and Pike were both formerly employed at Bell Labs. The initial design was begun in 2007 and the first implementation was released in late 2009. One of the initial motivations for Go was the slowness of compilation of large C++ programs at Google. One of the characteristics of the initial compiler for Go is that is it extremely fast. The Go language borrows some of its syntax and constructs from C. Some of the new features of Go include the following: (1) Data declarations are syntactically reversed from the other C-based languages; (2) the variables precede the type name; (3) variable declarations can be given a type by inference if the variable is given an initial value; and (4) functions can return multiple values. Go does not support traditional object-oriented programming, as it has no form of inheritance. However, methods can be defined for any type. It also does not have generics. The control statements of Go are similar to those of other C-based languages, although the switch does not include the implicit fall through to the next segment. Go includes a goto statement, pointers, associative arrays, interfaces (though they are different from those of Java and C#), and support for concurrency using its goroutines.
2.17 An Imperative-Based Object-Oriented Language: Java
Java’s designers started with C++, removed some constructs, changed some, and added a few others. The resulting language provides much of the power and flexibility of C++, but in a smaller, simpler, and safer language.
2.17.1Design Process
Java, like many programming languages, was designed for an application for which there appeared to be no satisfactory existing language. In 1990, Sun Microsystems determined there was a need for a programming language for embedded consumer electronic devices, such as toasters, microwave ovens, and interactive TV systems. Reliability was one of the primary goals for such a language. It may not seem that reliability would be an important factor in the software for a microwave oven. If an oven had malfunctioning software, it probably would not pose a grave danger to anyone and most likely would not lead to large legal settlements. However, if the software in a particular model was found to be erroneous after a million units had been manufactured and sold, their recall would entail significant cost. Therefore, reliability is an important characteristic of the software in consumer electronic products.

92 |
Chapter 2 Evolution of the Major Programming Languages |
After considering C and C++, it was decided that neither would be satisfactory for developing software for consumer electronic devices. Although C was relatively small, it did not provide support for object-oriented programming, which they deemed a necessity. C++ supported object-oriented programming, but it was judged to be too large and complex, in part because it also supported procedure-oriented programming. It was also believed that neither C nor C++ provided the necessary level of reliability. So, a new language, later named Java, was designed. Its design was guided by the fundamental goal of providing greater simplicity and reliability than C++ was believed to provide.
Although the initial impetus for Java was consumer electronics, none of the products with which it was used in its early years were ever marketed. Starting in 1993, when the World Wide Web became widely used, and largely because of the new graphical browsers, Java was found to be a useful tool for Web programming. In particular, Java applets, which are relatively small Java programs that are interpreted in Web browsers and whose output can be included in displayed Web documents, quickly became very popular in the middle to late 1990s. In the first few years of Java popularity, the Web was its most common application.
The Java design team was headed by James Gosling, who had previously designed the UNIX emacs editor and the NeWS windowing system.
2.17.2Language Overview
As we stated previously, Java is based on C++ but it was specifically designed to be smaller, simpler, and more reliable. Like C++, Java has both classes and primitive types. Java arrays are instances of a predefined class, whereas in C++ they are not, although many C++ users build wrapper classes for arrays to add features like index range checking, which is implicit in Java.
Java does not have pointers, but its reference types provide some of the capabilities of pointers. These references are used to point to class instances. All objects are allocated on the heap. References are always implicitly dereferenced, when necessary. So they behave more like ordinary scalar variables.
Java has a primitive Boolean type named boolean, used mainly for the control expressions of its control statements (such as if and while). Unlike C and C++, arithmetic expressions cannot be used for control expressions.
One significant difference between Java and many of its predecessors that support object-oriented programming, including C++, is that it is not possible to write stand-alone subprograms in Java. All Java subprograms are methods and are defined in classes. Furthermore, methods can be called through a class or object only. One consequence of this is that while C++ supports both procedural and object-oriented programming, Java supports object-oriented programming only.
Another important difference between C++ and Java is that C++ supports multiple inheritance directly in its class definitions. Java supports only single

2.17 An Imperative-Based Object-Oriented Language: Java |
93 |
inheritance of classes, although some of the benefits of multiple inheritance can be gained by using its interface construct.
Among the C++ constructs that were not copied into Java are structs and unions.
Java includes a relatively simple form of concurrency control through its synchronized modifier, which can appear on methods and blocks. In either case, it causes a lock to be attached. The lock ensures mutually exclusive access or execution. In Java, it is relatively easy to create concurrent processes, which in Java are called threads.
Java uses implicit storage deallocation for its objects, often called garbage collection. This frees the programmer from needing to delete objects explicitly when they are no longer needed. Programs written in languages that do not have garbage collection often suffer from what is sometimes called memory leakage, which means that storage is allocated but never deallocated. This can obviously lead to eventual depletion of all available storage. Object deallocation is discussed in detail in Chapter 6.
Unlike C and C++, Java includes assignment type coercions (implicit type conversions) only if they are widening (from a “smaller” type to a “larger” type). So int to float coercions are done across the assignment operator, but float to int coercions are not.
2.17.3Evaluation
The designers of Java did well at trimming the excess and/or unsafe features of C++. For example, the elimination of half of the assignment coercions that are done in C++ was clearly a step toward higher reliability. Index range checking of array accesses also makes the language safer. The addition of concurrency enhances the scope of applications that can be written in the language, as do the class libraries for graphical user interfaces, database access, and networking.
Java’s portability, at least in intermediate form, has often been attributed to the design of the language, but it is not. Any language can be translated to an intermediate form and “run” on any platform that has a virtual machine for that intermediate form. The price of this kind of portability is the cost of interpretation, which traditionally has been about an order of magnitude more than execution of machine code. The initial version of the Java interpreter, called the Java Virtual Machine ( JVM), indeed was at least 10 times slower than equivalent compiled C programs. However, many Java programs are now translated to machine code before being executed, using Just-in-Time ( JIT) compilers. This makes the efficiency of Java programs competitive with that of programs in conventionally compiled languages such as C++.
The use of Java increased faster than that of any other programming language. Initially, this was due to its value in programming dynamic Web documents. Clearly, one of the reasons for Java’s rapid rise to prominence is simply that programmers like its design. Some developers thought C++ was simply too

94 |
Chapter 2 Evolution of the Major Programming Languages |
large and complex to be practical and safe. Java offered them an alternative that has much of the power of C++, but in a simpler, safer language. Another reason is that the compiler/interpreter system for Java is free and easily obtained on the Web. Java is now widely used in a variety of different applications areas.
The most recent version of Java, Java 7, appeared in 2011. Since its beginning, many features have been added to the language, including an enumeration class, generics, and a new iteration construct.
The following is an example of a Java program:
//Java Example Program
//Input: An integer, listlen, where listlen is less
//than 100, followed by length-integer values
//Output: The number of input data that are greater than
//the average of all input values
import java.io.*; class IntSort {
public static void main(String args[]) throws IOException { DataInputStream in = new DataInputStream(System.in); int listlen,
counter, sum = 0, average, result = 0;
int[] intlist = new int[99];
listlen = Integer.parseInt(in.readLine()); if ((listlen > 0) && (listlen < 100)) {
/* Read input into an array and compute the sum */ for (counter = 0; counter < listlen; counter++) {
intlist[counter] = Integer.valueOf(in.readLine()).intValue();
sum += intlist[counter];
}
/* Compute the average */ average = sum / listlen;
/* Count the input values that are > average */
for (counter = 0; counter < listlen; counter++) if (intlist[counter] > average) result++;
/* Print result */ System.out.println(
"\nNumber of values > average is:" + result);
}//** end of then clause of if ((listlen > 0) ...
else System.out.println(
"Error—input list length is not legal\n");
}//** end of method main
}//** end of class IntSort