1.2. Programming Languages and Programs

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:

Programs based on the imperative paradigm perform computations based on state changes (where a program's state is its current condition or activity, and is determined by the values stored in all its variables at any given time). Simply put, imperative programs calculate values and store the values into variables for later use. Declarative programs focus on the computation logic rather than on the flow of data - these programming languages do not make assignments 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 pattern that defines a correct program represents 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# is derived
from Java.
The C++ family tree. C++ was derived from the C programming language and serves as the basis for the Java and C# programming languages. Java and Objective C were also greatly influenced by the Smalltalk programming language. Really, everything before C is irrelevant to the concepts covered here.

Programming languages are often described 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. First, it represents a mid-level language because it retains C's access to the hardware. But second, 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++ a popular choice 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 also high-level languages but are 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. Low-level programming languages are hardware-dependent and logically more distant from a given problem. Low-level languages can carry out primitive operations that are not possible in higher-level languages, but at the expense of making it more difficult to represent the elements of a given problem.

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 that are not related 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.