Some history
In the last few decades, we have been able to witness a rapid change
in the technology underlying our computer systems.
Simultaneously, our ideas of how to program these machines
have changed radically as well.
The history of programming languages may be regarded as a
progression from low level constructs towards high level abstractions,
that enable the programmer to specify programs in a more
abstract manner and hence allow problem related abstractions to
be captured more directly in a program.
This development towards high level languages was partly motivated
by the need to be able to verify that a program adequately
implemented a specification (given in terms of a formal description
of the requirements of an application).
Regarded from this perspective, it is then perhaps more appropriate
to speak of a progression of paradigms of programming,
where a paradigm must be understood as a set of mechanisms
and guidelines telling us how to employ these mechanisms.
The first abstraction mechanism beyond the level of assembler
language and macros is provided by procedures.
Procedures play an important role in
the method of stepwise refinement introduced by
the school of structured programming.
Stepwise refinement allows the specification of a complex algorithm gradually
in more and more detail.
Program verification amounts to establishing whether the implementation
of an algorithm in a programming language meets its specification
given in mathematical or logical terms.
Associated with the school of structured programming is a method
of verification based on what has become known as Hoare logic,
which proceeds by introducing assertions and establishing that
procedures meet particular pre- and post-conditions.
Other developments in programming language research aimed at providing
ways in which to capture the mathematical or logical meaning of a program
more directly.
These developments resulted in a number of functional programming
languages (e.g. ML, Miranda)
and logic programming languages, of which Prolog is the most
well-known.
The programming language Lisp may in this respect also be regarded
as a functional language.
The history of object-oriented programming may be traced back to
a concern for data abstraction, which was needed to deal
with algorithms that involved complex data structures.
The notion of objects, originally introduced
in Simula (Dahl and Nygaard, 1966), has significantly influenced the design
of many subsequent languages,(eg. CLU, Modula and Ada).
The first well-known object-oriented language
was Smalltalk,
originally developed to program the Dynabook,
a kind of machine that is now familiar to us as a laptop or notebook
computer.
In Smalltalk, the data hiding aspect of objects has been
combined with the mechanism of inheritance, allowing the reuse
of code defining the behavior of objects.
The primary motivation behind Smalltalk's notion of objects,
as a mechanism to manage the complexity of graphic user interfaces,
has now proven its worth, since it has been followed
by most of the manufacturers of graphic user interfaces and window systems.
Summarizing, from a historical perspective, the introduction of
the object-oriented approach may be regarded as a natural extension to
previous developments in programming practice, motivated
by the need to cope with the complexity of new applications.
History doesn't stop here. Later developments,
represented by Eiffel and to a certain extent C++,
more clearly reflected the concern with abstraction and verification,
which intrinsically belongs to the notion of abstract data types
as supported by these languages.