1.2. Programming Languages and Paradigms

Time: 00:02:45 | Download: Large, Large (CC) Small | Streaming Streaming (CC) | Slides (PDF)

We can categorize programming languages in many different ways. If we examine the kinds of problems they solve and the ways they calculate the solutions, two distinct approaches emerge, and we can further divide the second approach into three separate subcategories:

Imperative-paradigm programs conditionally perform the operations based on their current state (1 & 3). Less formally, imperative programs calculate values and store the values into variables for later use. Alternatively, declarative programs focus on what the program must do rather than on the data flow - these programming languages do not assign values to variables. Declarative "languages are 'higher level' than imperative languages, in that the programmer operates more remotely from the CPU itself" (Appleby and VandeKopple, 1997, p. 9).

Programs written in imperative languages (like Java and C++) consist of a sequence of statements, where each statement is an instruction that causes the computer to do one operation. Statements, and therefore programs, are composed of a pattern of keywords, symbols, and programmer-named entities. The patterns defining correct programs represent the programming language's syntax.

C++ is an imperative programming language that traces its lineage to FORTRAN, the first high-level programming language.

The derivation of C++ from FORTRAN: FORTRAN, ALGOL58, ALGOL60, CPL, BCPL, B, and C.
Both C++ and Objective C are derived from C. Java is derived from C++, and C# from Java.
The C++ family tree. C++ was derived from the C programming language and was the basis for the Java and C# programming languages. Java and Objective C were also greatly influenced by the Smalltalk programming language. Many concepts and much of the terminology used throughout the text originate with ALGOL, but regarding C++'s syntax, everything before C is irrelevant.

Computer scientists often describe programming languages as high-level or low-level. High-level programming languages are (mostly) independent of the hardware. Programmers can move hardware-independent code from one computer to another fairly easily. High-level languages include features that reflect or align with elements of the problem domain. These features make it easier for computer scientists to solve problems with computer programs.

Low-level languages are very dependent on the computer hardware, so it takes much more effort for programmers to move the source code from one computer to another. Being tied to the hardware means that low-level languages reflect the primitive operations that the hardware can perform rather than providing the features that clearly and easily represent a problem.

The C programming language is deemed a mid-level language because it allows programmers more access to the hardware than other, higher-level languages. But it also provides the problem-centered constructs seen in high-level programming languages. We can locate C++ at two different places in this spectrum. It represents a mid-level language because it retains C's access to the hardware. But, it also represents a high-level language because it supports object orientation, a problem-centered approach to programming. The combination of high- and mid-level features makes C++ popular for writing games, operating systems, and large applications.

A graphic showing the relationship between several programming languages. SQL and other declarative languages are the highest-level languages. Java and C# are among the highest-level imperative languages. FORTRAN, COBOL, and C++ are high-level languages below Java and C#. C is a mid-level language. Assembler and machine code are the lowest-level languages.
High-level vs. low-level programming languages. High-level programming languages are generally hardware-independent and problem-centered (providing operations supporting general problem-solving). Low-level programming languages are hardware-dependent and machine-centered (providing operations matching the hardware's capabilities). Low-level languages can carry out primitive operations not possible in higher-level languages but at the expense of making it more difficult to represent the features of a given problem.

C is a mid-level programming language designed for creating operating systems. It can perform some primitive operations that most higher-level languages cannot but also provides problem-centered operations. C++ inherits C's primitive operations while adding high-level object-oriented capabilities.

C is a nearly perfect subset of C++, meaning that (with few obscure exceptions) a C++ compiler can compile a correct C program. C++ extends the C programming language by adding:

A Venn diagram showing C as a subset of C++.
The relationship between ANSI C and C++. C++ extends C in two basic directions. First, it adds support for object-oriented programming. But C++ also extends C with improved programming features unrelated to object-oriented programming. Some C++ features (e.g., prototypes and the const keyword) were back-ported to K&R C to form the ANSI C version of the language.


Appleby, D. and VandeKopple, J.J. (1997). Programming Languages: Paradigm and Practice (2nd Ed). The McGraw-Hill Companies, Inc., New York.