
- •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

Review Questions |
235 |
Scalar variables can be separated into four categories by considering their lifetimes: static, stack dynamic, explicit heap dynamic, and implicit heap dynamic.
Static scoping is a central feature of ALGOL 60 and some of its descendants. It provides a simple, reliable, and efficient method of allowing visibility of nonlocal variables in subprograms. Dynamic scoping provides more flexibility than static scoping but, again, at the expense of readability, reliability, and efficiency.
Most functional languages allow the user to create local scopes with let constructs, which limit the scope of their defined names.
The referencing environment of a statement is the collection of all of the variables that are visible to that statement.
Named constants are simply variables that are bound to values only once.
R E V I E W Q U E S T I O N S
1.What are the design issues for names?
2.What is the potential danger of case-sensitive names?
3.In what way are reserved words better than keywords?
4.What is an alias?
5.Which category of C++ reference variables is always aliases?
6.What is the l-value of a variable? What is the r-value?
7.Define binding and binding time.
8.After language design and implementation [what are the four times bindings can take place in a program?]
9.Define static binding and dynamic binding.
10.What are the advantages and disadvantages of implicit declarations?
11.What are the advantages and disadvantages of dynamic type binding?
12.Define static, stack-dynamic, explicit heap-dynamic, and implicit heapdynamic variables. What are their advantages and disadvantages?
13.Define lifetime, scope, static scope, and dynamic scope.
14.How is a reference to a nonlocal variable in a static-scoped program connected to its definition?
15.What is the general problem with static scoping?
16.What is the referencing environment of a statement?
17.What is a static ancestor of a subprogram? What is a dynamic ancestor of a subprogram?
18.What is a block?
19.What is the purpose of the let constructs in functional languages?
20.What is the difference between the names defined in an ML let construct from the variables declared in a C block?

236Chapter 5 Names, Bindings, and Scopes
21.Describe the encapsulation of an F# let inside a function and outside all functions.
22.What are the advantages and disadvantages of dynamic scoping?
23.What are the advantages of named constants?
P R O B L E M S E T
1.Which of the following identifier forms is most readable? Support your decision.
SumOfSales sum_of_sales SUMOFSALES
2.Some programming languages are typeless. What are the obvious advantages and disadvantages of having no types in a language?
3.Write a simple assignment statement with one arithmetic operator in some language you know. For each component of the statement, list the various bindings that are required to determine the semantics when the statement is executed. For each binding, indicate the binding time used for the language.
4.Dynamic type binding is closely related to implicit heap-dynamic variables. Explain this relationship.
5.Describe a situation when a history-sensitive variable in a subprogram is useful.
6.Consider the following JavaScript skeletal program:
// The main program var x;
function sub1() {
var x;
function sub2() {
...
}
}
function sub3() {
...
}
Assume that the execution of this program is in the following unit order:
main calls sub1
sub1 calls sub2
sub2 calls sub3

Problem Set |
237 |
a.Assuming static scoping, in the following, which declaration of x is the correct one for a reference to x?
i.sub1
ii.sub2
iii.sub3
b.Repeat part a, but assume dynamic scoping.
7.Assume the following JavaScript program was interpreted using static-scoping rules. What value of x is displayed in function sub1? Under dynamic-scoping rules, what value of x is displayed in function sub1?
var x;
function sub1() {
document.write("x = " + x + "<br />");
}
function sub2() {
var x; x = 10; sub1();
}
x = 5; sub2();
8. Consider the following JavaScript program:
var x, y, z; function sub1() {
var a, y, z;
function sub2() {
var a, b, z;
...
}
...
}
function sub3() {
var a, x, w;
...
}

238 |
Chapter 5 Names, Bindings, and Scopes |
List all the variables, along with the program units where they are declared, that are visible in the bodies of sub1, sub2, and sub3, assuming static scoping is used.
9. Consider the following Python program:
x = 1; y = 3;
z = 5;
def sub1():
a = 7;
y = 9;
z = 11;
...
def sub2():
global x;
a = 13;
x = 15;
w = 17;
...
def sub3():
nonlocal a;
a = 19;
b = 21;
z = 23;
...
...
List all the variables, along with the program units where they are declared, that are visible in the bodies of sub1, sub2, and sub3, assuming static scoping is used.
10. Consider the following C program:
void fun(void) {
int a, b, c; /* definition 1 */
...
while (...) {
int b, c, d; /*definition 2 */
... 1
while (...) {

Problem Set |
239 |
int c, d, e; /* definition 3 */
... 2
}
... 3
}
... 4
}
For each of the four marked points in this function, list each visible variable, along with the number of the definition statement that defines it.
11. Consider the following skeletal C program:
void fun1(void); void fun2(void); void fun3(void); void main() {
/* prototype */ /* prototype */ /* prototype */
int a, b, c;
...
}
void fun1(void) {
int b, c, d;
...
}
void fun2(void) {
int c, d, e;
...
}
void fun3(void) {
int d, e, f;
...
}
Given the following calling sequences and assuming that dynamic scoping is used, what variables are visible during execution of the last function called? Include with each visible variable the name of the function in which it was defined.
a. main calls fun1; fun1 calls fun2; fun2 calls fun3.
b.main calls fun1; fun1 calls fun3.
c.main calls fun2; fun2 calls fun3; fun3 calls fun1.

240Chapter 5 Names, Bindings, and Scopes
d.main calls fun3; fun3 calls fun1.
e. main calls fun1; fun1 calls fun3; fun3 calls fun2.
f.main calls fun3; fun3 calls fun2; fun2 calls fun1.
12.Consider the following program, written in JavaScript-like syntax:
// main program var x, y, z;
function sub1() { var a, y, z;
...
}
function sub2() { var a, b, z;
...
}
function sub3() { var a, x, w;
...
}
Given the following calling sequences and assuming that dynamic scoping is used, what variables are visible during execution of the last subprogram activated? Include with each visible variable the name of the unit where it is declared.
a. |
main calls sub1; sub1 calls sub2; sub2 calls sub3. |
b. |
main calls sub1; sub1 calls sub3. |
c. |
main calls sub2; sub2 calls sub3; sub3 calls sub1. |
d. |
main calls sub3; sub3 calls sub1. |
e. |
main calls sub1; sub1 calls sub3; sub3 calls sub2. |
f. |
main calls sub3; sub3 calls sub2; sub2 calls sub1. |
P R O G R A M M I N G E X E R C I S E S
1.Perl allows both static and a kind of dynamic scoping. Write a Perl program that uses both and clearly shows the difference in effect of the two. Explain clearly the difference between the dynamic scoping described in this chapter and that implemented in Perl.

Programming Exercises |
241 |
2.Write a Common LISP program that clearly shows the difference between static and dynamic scoping.
3.Write a JavaScript script that has subprograms nested three deep and in which each nested subprogram references variables defined in all of its enclosing subprograms.
4.Repeat Programming Exercise 3 with Python.
5.Write a C function that includes the following sequence of statements:
x = 21;
int x;
x = 42;
Run the program and explain the results. Rewrite the same code in C++ and Java and compare the results.
6.Write test programs in C++, Java, and C# to determine the scope of a variable declared in a for statement. Specifically, the code must determine whether such a variable is visible after the body of the for statement.
7.Write three functions in C or C++: one that declares a large array statically, one that declares the same large array on the stack, and one that creates the same large array from the heap. Call each of the subprograms a large number of times (at least 100,000) and output the time required by each. Explain the results.
This page intentionally left blank

6
Data Types
6.1Introduction
6.2Primitive Data Types
6.3Character String Types
6.4User-Defined Ordinal Types
6.5Array Types
6.6Associative Arrays
6.7Record Types
6.8Tuple Types
6.9List 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 |
243