Programming Paradigms

Programming is a state of mind. Here are the motivations for some of the states.

Computers

There is a well-developed mathematical theory of computers. According to this theory, all ordinary computers are equivalent, in the sense that anything that can be done with one computer can, in principle, be done with any other computer. Similarly, all ordinary computer languages are equivalent, in the sense that any program that can be written in one language can be written in any other.

Despite the formal equivalence of all computers, some may be better-suited to a given task than others. Similarly, most computer languages are designed to facilitate certain operations and not others: numerical computation, or text manipulation, or I/O. More broadly, a computer language typically embodies a particular programming paradigm. More than just a collection of features, a paradigm is a way of thinking about problems and their solutions, and an approach to using computers to implement those solutions. Three important paradigms are described below.

Algorithms

The first computers were used to solve mathematical problems that arose in large military and scientific projects. These problems include numerical evaluation of definite integrals, numerical solution of differential equations and simulation of stochastic processes (Monte Carlo simulation).

In this kind of work, algorithms are permanent and data is transient. Each algorithm represents a large investment in scientific and programming effort. The algorithm is kept on, or near, the computer. Users bring their problem to the computer, run the algorithm, and then leave with their results.

Programming languages that are primarily designed to express algorithms are called procedural languages. They include FORTRAN, Algol, C and Pascal.

Databases

In the 1950's large businesses started using computers. Banks put their customers' checking accounts on computers. Insurance companies put their policies on computers. And firms of all kinds used computers to run their accounting and payroll operations.

In business applications, data is permanent and algorithms are transient. A firm's data, coded and recorded on a computer system, represents an enormous investment. This collection of data is called a database, and is carefully tended and protected. Small algorithms, called transactions, come to the database, execute, and leave. For example, each time you take money out of an ATM, a transaction operates on a database to debit your bank balance.

Conceptually, a database and its transactions are simpler than the mathematics that underlie much algorithmic programming. However, database programming involves complex and subtle issues, and is often more difficult than algorithmic programming. Programming languages that are designed to manage databases are called database systems. On PC's, the most widely used database system is DBase. On Unix systems, many people use Sybase.

Objects

GUIs

In the 1980's, individuals started using computers. Typical applications included spreadsheets, word processors and computer aided design (CAD). Many of the people using these applications had no technical background. One consequence of this was that user interface design became important. It was no longer sufficient that a program work; in addition, it had to make its functionality accessible to users who did not have specialized training.

Many different user interfaces have been tried. One of the most successful is the graphical user interface (GUI). This is the kind of interface provided by the Macintosh, Motif, Tk, and Microsoft Windows. It includes a mouse and a graphical display, with windows, menus, dialog boxes, scroll bars and so on.

Just like the real thing

When vendors advertise GUIs, they emphasize the graphics. Graphics are, after all, what the user sees. However, the graphical display is only a component of a GUI. The real power of a GUI flows from the fact that objects on the screen behave like objects in the real world.

You can move a window on the screen, just as you can move a piece of paper on your desk. Clicking in a button on the screen makes something happen, just like pushing a button in an elevator. Things on the screen only move if you move them, just like things in the real world.

Most users consider GUIs to be simple and natural. They're half right. A GUI is natural, in that it embodies properties of the real world. However, those properties are not particularly simple. The reason that people find GUIs easy to use is that the human brain has evolved to function in the real world. By mimicking the real world in certain ways, a GUI can leverage the power of the human perceptual system, thus making the functionality of the application easily accessible to the user.

Reality is complex

GUIs mimic aspects of the real world. However, the real world is complex, and this makes GUIs difficult to program.

Strictly speaking, a GUI is an algorithm. It accepts input and generates output. However, the input comes from a human, and is therefore very complex. The user could click and then type, or type and then move the mouse, or open one window and then close another, or insert a disk, etc., etc. A GUI must behave correctly and consistently no matter what the variety and sequence of user inputs. A single algorithm to do this would be very complex.

Alternately, a GUI can be viewed as a database. The database contains all the information about the things on the screen: positions and contents of windows, fill patterns and colors, cursor shape, etc. Each user action invokes a transaction that alters some of the data. The problem here is that the data in a GUI is ill-suited to a database system. There isn't very much of it, but what there is tends to be varied and complex. Database systems are better at handling large, homogeneous datasets, such as the names and social security numbers of all US citizens.

Object-oriented programming systems

The need to program GUIs led to a distinct programming paradigm, called object-oriented programming. An object-oriented programming system (OOPS) consists of objects. An object comprises both data and algorithms. The data describes the state of the object. Objects communicate by sending messages to each other. When an object receives a message, it responds by executing one of its algorithms. The algorithm may change the state of the object, generate output, or send messages to other objects.

OOPS are well-suited to programming GUIs. Typically, each element of a GUI is represented by one object. The object determines both the state and the behavior of the corresponding element. For example, an object representing a window would have data for its position, size and title. If the user closes the window, the OOPS sends a message to the window object telling it to close itself. The window then executes an algorithm that erases its image from the screen.

Benefits

In a broad sense, the greatest benefit of an object-oriented programming system is that it imposes a powerful structure on computer programs. This structure can make complex, intricate systems, such as GUIs, manageable. Several features that contribute to this structure are:

Modularity

The objects in an OOPS are self-contained, and have clearly defined interfaces to other objects. This facilitates writing modular code, which reduces the inherent complexity of a program.

Polymorphism

An OOPS can have many different kinds of objects, and new objects can inherit properties of existing objects. For example, a GUI might have several kinds of windows: document windows, dialog boxes, help screens, etc. An OOPS would typically define a window object, and then define specialized sub-objects for each particular kind of window. Again, this helps to manage the complexity of the program.

Extensibility

If an OOPS provides for three kinds of windows, it can as easily provide for four, or five. Adding a new feature is often simply a matter of defining an object to implement it. Furthermore, new sub-objects can be defined without having to modify, or even see, the original code.

In principle, the same thing can be done in a procedural language. However, for technical reasons, it is more difficult, and it very often corrupts the original design of the program, leading to unmanageable complexity.

Non-benefits

Object-oriented programming has real benefits. However, it is not a panacea. Here are a few caveats:

Hard is hard

An OOPS gives you the tools to manage complexity; it doesn't give you the ability to do so. If a program isn't well designed to begin with, an OOPS isn't going to help.

If all you have is a hammer...

Not everything is an object. Numerical integration and bank statements are best left to procedural languages and database systems, respectively.

C++

Currently, the most widely used OOPS is C++. C++ is a superset of the C language. C is widely used through industry and academia; compatibility with C accounts for much of the popularity of C++.

Unfortunately, C is a procedural language and C++ is an OOPS. There are profound differences between these two paradigms, and trying to include both in a single language leads to many difficulties.

Reusability

One of the purported benefits of object-oriented programming is that objects can be placed in libraries for all to use (or buy). This saves the world the effort of continually rewriting the same code for every new program. Furthermore, because objects are extensible (see above), object libraries offer the programmer more flexibility and functionality than subroutine libraries (their counterparts in procedural languages).

Technically, object libraries are quite feasible, and the advantages of extensibility can be significant. However, the real challenge to making code reusable is not technical. Rather, it is identifying functionality that other people both understand and want.

People who use procedural languages have been writing and using subroutine libraries for decades. These libraries are most successful when they perform simple, clearly defined functions, such as extracting square roots or computing trigonometric functions.

An object library can provide complex functions more easily than a subroutine library can. However, unless those functions are clearly defined, well understood and generally useful, the library is unlikely to be widely used.


Notes

led
Experimental object-oriented programming systems were developed in academia as early as the 1960s. However, they remained academic until the 1980s, when the commercial world adopted them to write GUIs.

Steven W. McDougall / resume / swmcd@world.std.com / September 1993