Programming languages were used even before computers were invented. For example, a player piano scroll, that long roll of encoded paper tape, is considered an early form of programming because it contained the instructions needed to make a piano play a tune.
The first computers were programmed by flipping switches and changing the configuration of the hardware. As a result, early programmers had to be intimately familiar with computer hardware. But we’ve come a long way, and high-level programming languages require little or no knowledge of the underlying hardware.
Let's take a look at how we got this far by covering the five generations of computer programming languages. (Get some background on some of the key figures in the field in The Pioneers of Computer Programming.)
The First Generation – Programming at the Machine Level
First-generation programming languages (1GL) are often known as machine languages or machine code. They operate at the lowest level of abstraction (closest to the hardware) of all languages. First-generation languages deal directly with the binary zeros and ones that are used to store and process information in a computer. Programs in higher-level languages must be compiled or assembled into machine code in order to run.
The Second Generation – Some Assembly Required
Second-generation languages (2GL), often known as assembly languages, were developed largely because of the difficulty in programming with first-generation languages. Although still low-level languages, assembly languages introduced the use of symbolic codes (called mnemonics) to represent instructions to the computer. A program in assembly language is translated into machine code by means of a utility known as an assembler.
Since they operate at the lowest level of abstraction, second-generation languages offer the benefits of speed and minimum code size. They also enable a programmer to directly manipulate hardware components such as memory locations and registers. At one time, assembly languages were used to program operating systems and applications that required smaller, faster-running code, such as video games. Examples of games written in assembly language include console games for the Mega Drive/Genesis platform and the Super Nintendo Entertainment System platform.
Although largely supplanted by higher-level languages, assembly languages are still used in situations where hardware interaction is required or performance must be optimized. Some compilers for higher-level languages compile source code to an assembly language before invoking an assembler to compile to machine code.
The Third Generation – Gentleman’s C and Others
The third generation of programming languages (3GL) includes high-level languages such as C, C++, Fortran, COBOL, BASIC, C# and Java. Third-generation programming languages represent a major improvement in usability over assembly languages.
Unlike assembly languages, third-generation languages are not machine-specific. When programming with a third-generation language, a programmer writes the source code for the program and then uses a compiler to translate it into object code (or machine code), which can be understood by the targeted computer.
The development of programming paradigms such as structured programming and object-oriented programming (OOP) coincided with the development of third-generation languages.
The Fourth Generation – Programmer Enhancement
Fourth-generation programming languages (4GL) were created to enhance programmer productivity in specific domains such as database querying and report generation.
The syntax of a fourth-generation language is generally closer to human language than the syntax from previous generations of programming languages. A single statement in a fourth-generation language can automatically generate the equivalent of a series of instructions in a third-generation language, reducing the time it takes to develop an application.
Examples of fourth-generation languages include Structured Query Language (SQL), Informix-4GL and ColdFusion.
The Fifth Generation – Watson, I Presume
The traditional unit of computation is the algorithm, which is basically a step-by-step procedure for calculating a solution. Fifth-generation languages attempt to go beyond the algorithm by defining the conditions (or properties) for a solution and allowing the computer to determine the possible solutions that meet the specified conditions.
Why Should I Care?
There you have it, the generations of programming languages really aren't that hard to understand. A good mental model is the higher up you get, the further abstracted you are from the hardware. This means less control, but also less work to accomplish something through programming.
Why does this matter? While theoretical, it's key to understand where your development fits in. Many developers spend the majority of their day in an integrated development environment for a 3GL language, so understanding that a language is 2GL or 4GL gives you some perspective as to the level of detail required to produce usable code. In general, working with a 2GL language is going to be more complex than a 3GL language. On the other hand, you can accomplish much less with a 4GL language like SQL than with a 3GL like C.
Where to From Here?
Will there be additional generations of programming languages? Some computer professionals consider graphical development environments to be a separate programming language generation. With the advent of apps, it's easier and easier to develop new software. Some people also point to concepts like "build your own app" as evidence that even regular users will be developers in certain areas. In any event, it’s likely that future generations of programmers will have new generations of programming languages to assist them.