This text is intended for computer science and computer engineering students in their sophomore year of study. It is assumed that students have completed a basic computer science course and have learned a high-level programming language like Pascal, C, C++, or Java. Most parts of the contents presented in the text have been used in the "Introduction to Programming Languages" course taught by the author in the School of Computer Science at the University of the Witwatersrand at Johannesburg, and in the Computer Science and Engineering Department at Arizona State University. Being different from the existing texts on programming languages that either focus on teaching programming paradigms, principles, and the language mechanisms, or focus on language constructs and programming skills, this text takes a balanced approach on both sides. It teaches four programming languages representing four major programming paradigms. Programming paradigms, principles, and language mechanisms are used as the vehicle to facilitate learning of the four programming languages in a coherent way. The goals of such a programming course are to make sure that computer science students are exposed to different programming paradigms and language mechanisms, and obtain sufficient programming skills and experiences in different programming languages, so that they can quickly use these or similar languages in other courses. Although there are many different programming paradigms, imperative, object-oriented, functional, and logic programming paradigms are the four major paradigms widely taught in computer science and computer engineering departments around the world. The four languages we will study in the text are the imperative C, object-oriented C++, functional Scheme, and logic Prolog.
By the end of the course, students should understand
- the language structures at different layers (lexical, syntactic, contextual, and semantic), the control structures and the execution models of imperative, object-oriented, functional, and logic programming languages;
- program processing (compilation versus interpretation) and preprocessing (macros and inlining);
- different aspects of a variable, including its type, scope, name, address, memory location, and value.
More specific features of programming languages and programming issues are explored in cooperation with the four selected languages. Students are expected to have understood and be able to
- write C programs with complex data types, including pointers, arrays, and generic structures, as well as programs with static and dynamic memory allocation;
- apply the object-oriented features such as inheritance and class hierarchy, polymorphism and typing, overloading, early versus late binding, as well as the constructors, the destructor and the management of static memory, stack and heap in C++;
- apply the functional programming style of parameter passing and write Scheme programs requiring multiple functions;
- apply the logic programming style of parameter passing, write Prolog facts, rules and goals, and use multiple rules to solve problems;
- be able to write programs requiring multiple subprograms/procedures to solve large programming problems;
- be able to write recursive subprograms/procedures in imperative, object-oriented, functional and logic programming languages.
The text is organized into five chapters and three appendices. Chapter one discusses the programming paradigms, principles, and common aspects of programming languages. Chapter two uses C as the example of the imperative programming paradigm to teach how to write imperative programs. It is assumed that the students have basic understanding of a high-level programming language such as Pascal, C, C++, or Java. Chapter three extends the discussion and programming from C to C++. The chapter focuses on the main features of object-oriented programming paradigms, including class composition, inheritance, dynamic memory allocation and deallocation, late binding, polymorphism, and class hierarchy. Chapters four and five take a major paradigm shift to teach functional and logic programming, respectively. Students are not required to have any knowledge in functional and logic programming to learn from these two chapters. Assignments, programming exercises, and projects are given at the end of each chapter. The three appendices provide supplementary materials to the main text. In Appendix A, the basic computer architecture and assembly language programming are introduced. If students do not have basic computer science background, the material should be covered in the class. Appendix B first introduces basic Unix commands. If the class uses a Unix-based laboratory environment, students can read the appendix to get started with Unix. Then the appendix introduces the major programming language environments that can be used to support teaching the four programming languages. Appendix C gives the ASCII code table that is referred in various parts of the text. In the main text, the sections with an asterisk mark are optional and can be skipped if time does not permit to cover all the material. Chapters four and five are self-contained and can be taught independently, or in a different order.
I wish to thank all those who have contributed to the materials and to the formation of this text. Particularly, I would like to thank my colleagues, Scott Hazelhurst and Conrad Mueller, of the University of the Witwatersrand, and Richard Whitehouse of Arizona State University who shared their course materials with me. Parts of these materials were used in teaching the programming languages course and used in this text. Thomas Boyd, Joe DeLibero, and Renee Turban of Arizona State University reviewed the final draft of the text and made constructive suggestions and useful comments. My teaching assistants Ibraz Mohammed, Jianchun Fan, Harish Bashettihalli, and Rajanikanth Mitta, helped me in the past few years prepare the assignments and programming exercises.
Raynette Brodie,
the student consultant for Microsoft at Arizona State University, contributed
the section "From C++ to C#" and the C# related materials in other sections.
Peter Hallam, C# developer at Microsoft, made very useful comments on C#
related topics. The major part of chapter five, sections 5.1 through 5.7, was reprinted (arranged by the publisher) from Tom Hankins and Thom Luce's book Prolog Minimanual.
I also would like to thank the editoral team, Jay Hays, Billee Jo Hefel, and Lynne Rogers at Kendall/Hunt Publishing. Jay pushed me into the position to write the text, Billee Jo checked my progress constantly that made me finally meet the deadline, and Lynne completed the production process.
The text was written while I was carrying out a full university workload. I am thankful to my family, Wei, George, and Jane. I could not imagine that I would be able to complete the task without their generous support by allowing me to use most of the weekends in the past year to write the text.
Although I have used the materials in teaching the programming languages courses at the University of the Witwatersrand, Johannesburg and at Arizona State University for several years, the text was put together in a short period of time. There are certainly many errors of different kinds. I would appreciate it if you could send me any corrections, comments, or suggestions for improving the text. My email address dedicated to dealing with the responses to the text is <text.cse240@asu.edu>. Instructors who use the text can contact the author for instructional support, including lecture slides in PowerPoint format and the solutions to the assignments.Yinong Chen
Table of Contents Preface
Basic Principles of Programming Languages 1
1.1 Introduction 2
1.1.1 Programming Concepts and Paradigms 2
1.1.2 Program Performance and Features of Programming Languages 3
1.1.3 Development of Programming Languages 3
1.2 Structures of Programming Languages 6
1.2.1 Lexical Structure 6
1.2.2 Syntactic Structure 7
1.2.3 Contextual Structure 7
1.2.4 Semantic Structure 8
*1.2.5 BNF Notation 8
1.2.6 Syntax Graph 10
1.3 Data Types and Type Checking 10
1.3.1 Data Types and Type Equivalence 11
1.3.2 Type Checking and Type Conversion 11
1.3.3 Orthogonality 12
1.4 Program Processing and Preprocessing 14
1.4.1 Interpretation and Compilation 15
1.4.2 Preprocessing: Macro and Inlining 16
*1.5 Program Development 19
1.5.1 Program Development Process 20
1.5.2 Program Testing 20
1.5.3 Correctness Proof 23
1.6 Summary 25
1.7 Homework and Programming Exercises 27
The Imperative Programming Languages, C/C++ 37
2.1 Getting Started with C/C++ 38
2.1.1 Write Your First C/C++ Program 38
2.1.2 Basic Input and Output Functions 39
2.1.3 Formatted Input and Output Functions 39
2.2 Control Structures in C/C++ 41
2.2.1 Operators and The Order of Evaluation 42
2.2.2 Basic Selection Structures (if-then-else and the conditional expression) 43
2.2.3 Multiple Selection Structure (switch) 44
2.2.4 Iteration Structures (while, do-while and for) 47
2.3 Data and Basic Data Types in C/C++ 48
2.3.1 Declaration of Variables and Functions 49
2.3.2 Scope Rule 50
2.3.3 Basic Data Types 51
2.4 Complex Types 53
2.4.1 Array 53
2.4.2 Pointer 56
2.4.3 String 58
2.4.4 Constants 64
2.4.5 Enumeration Type 65
2.5 Compound Data Types 68
2.5.1 Structure Types 68
2.5.2 Union 69
2.5.3 Collection of Structures Using Static Memory Allocation 70
2.5.4 Collection of Structures Using Dynamic Memory Allocation 73
2.5.5 File and File Operations 76
2.6 Functions and Parameter Passing 81
2.7 Modular Design 84
2.8 Summary 85
2.9 Homework, Programming Exercises, and Projects 87
The Object-Oriented Programming Language, C++ 109
3.1 A Long Program Example: A Queue and a Priority Queue Written in C++ 110
3.2 Class Definition and Composition 113
3.2.1 Class Definition 113
3.2.2 Scope Resolution Operator 114
3.2.3 Objects From a Class 114
3.2.4 Definition of Constructor and Destructor 115
3.3 Memory Management and Garbage Collection 116
3.3.1 Static: Global Variables and Static Local Variables 117
3.3.2 Runtime Stack for Local Variables 118
3.3.3 Heap: Dynamic Memory Allocation 120
3.3.4 Scope and Garbage Collection 120
3.4 Inheritance 124
3.4.1 Class Containment and Inheritance 124
3.4.2 Inheritance and Hierarchy 127
3.4.3 Inheritance and Polymorphism 142
3.4.4 Polymorphism and Type Checking 144
3.4.5 Polymorphism and Late Binding 144
*3.5 From C++ to C# 145
3.5.1 Namespaces and The Using Directive 145
3.5.2 The Queue Example in C# 146
3.5.3 Class and Object in C# 147
3.5.4 Parameters: Passing by Reference with ref & out 148
3.5.5 Base Classes and Constructors 149
3.5.6 Constructor, Destructor, and Garbage Collection 149
3.5.7 Pointers in C# 150
3.5.8 C# Unified Type System 151
3.5.9 Further Topics in C# 152
3.6 Summary 153
3.7 Homework, Programming Exercises, and Projects 155
The Functional Programming Language, Scheme 161
4.1 From Imperative Programming to Functional Programming 162
4.2 Prefix Notation 164
4.3 Basic Scheme Terminology 167
4.4 Basic Scheme Data Types and Functions 169
4.4.1 Number 169
4.4.2 Boolean 170
4.4.3 Character 171
4.4.4 String 172
4.4.5 Symbol 173
4.4.6 Pair 173
4.4.7 List 174
4.4.8 Quotes 175
4.4.9 Definition of Procedure and Procedure Type 176
4.4.10 Input/Output and Non-functional Features 178
*4.5 Lambda-Calculus 180
4.5.1 Lambda l-Expressions 181
4.5.2 l-procedure and Parameter Scope 181
4.5.3 Reduction Rules 182
4.6 Define your Scheme Procedures and Macros 183
4.6.1 Unnamed Procedures 183
4.6.2 Named Procedures 184
4.6.3 Scopes of Variables and Procedures 184
4.6.4 Let-form and Unnamed Procedure 186
4.6.5 Macros 187
4.7 Structure of Recursive Procedures 188
4.7.1 Control Structure of Recursive Procedures 188
4.7.2 Simple Steps of Writing Recursive Procedures 190
4.7.3 Case Study: Solving Hanoi Tower Problem 191
4.8 Define Recursive Procedures on Data Types 194
4.8.1 Number Manipulations 194
4.8.2 Character and String Manipulations 197
4.8.3 List Manipulations 198
4.9 Higher Order Functions 199
4.9.1 Mapping 199
4.9.2 Filtering 201
4.10 Summary 202
4.11 Homework, Programming Exercises, and Projects 203
The Logic Programming Language, Prolog 219
5.1 A First Look at Prolog 219
5.1.1 Brief Background 219
5.1.2 Arity Prolog 220
5.1.3 A Prolog Program 220
5.1.4 Putting Prolog to Work by Querying the Database 222
5.2 Rules, Structured Data and The Scope of Variables 225
5.2.1 Rules and How They Work 225
5.2.2 Structures 228
5.2.3 The Scope of Prolog Variables 231
5.3 Operators and Functions 231
5.3.1 Operators 232
5.3.2 Arithmetic 234
5.3.3 Using the Operators 235
5.4 Recursion and Recursive Rules 238
5.4.1 Recursion as a Generalization of Non-Recursive Rules 239
5.4.2 Suggestions for Writing Recursive Rule Sets 242
5.4.3 Finding Factorial Values 242
5.4.4 The Towers of Hanoi 244
5.5 Lists 245
5.5.1 Referencing Lists 245
5.5.2 Examining The Elements of a List 248
5.5.3 Forming New Lists 251
5.5.4 Other List Predicates 253
5.6 Input and Output 254
5.6.1 Reading and Writing 258
5.6.2 Database Manipulation Predicates 260
5.6.3 Input and Output Examples 261
5.6.4 File I/O 263
5.7 Program Control and Program Design 264
5.7.1 Control Program Execution 265
5.7.2 Programming Suggestions 269
5.8 Homework, Programming Exercises, and Projects 271
Appendix A Basic Computer Architectures and Assembly Language Programming 281
A.1 Basic Computer Components and Computer Architectures 281
A.2 Computer Architectures and Assembly Programming 282
A.3 Subroutines and Local Variables on Stack 286
Appendix B Programming Environments Supporting C, C++, Scheme, and Prolog
B.1 Introduction to Unix Commands 289
B.2 Programming Environments Supporting C, C++, and C# Programming 292
B.2.1 Getting Started with GNU GCC under Unix Operating System 292
B.2.2 Getting Started with Visual Studio C++ under MS Windows Operating System 293
B.2.3 Getting Started with Visual Studio .Net under MS Windows Operating System
B.2.4 Download C, C++, and C# Programming Development Tools 294
B.3 Programming Environments Supporting Scheme Programming 294
B.3.1 Getting Started with DrScheme 294
B.3.2 Download DrScheme Programming Environment 295
B.4 Programming Environments Supporting Prolog Programming 295
B.4.1 Getting Started with GNU Prolog 295
B.4.2 Download Prolog Programming Development Tools 296
Appendix C ASCII Character Table 299
References 303
Index 305