Comparative Programming
Comparative Programming
Programming languages
3
4 Chapter 1 Programming languages
Just as important as the individual concepts are the ways in which they may
be put together to design complete programming languages. Different selections
of key concepts support radically different styles of programming, which are
called paradigms. There are six major paradigms. Imperative programming is
characterized by the use of variables, commands, and procedures; object-oriented
programming by the use of objects, classes, and inheritance; concurrent pro-
gramming by the use of concurrent processes, and various control abstractions;
functional programming by the use of functions; logic programming by the use of
relations; and scripting languages by the presence of very high-level features. We
shall study all of these paradigms in Part IV of this book.
FORTRAN
LISP
ALGOL60 COBOL 1960
PL/I
SIMULA
ALGOL68
PASCAL 1970
SMALLTALK PROLOG
C
MODULA
ML
1980
ADA83
C++
HASKELL 1990
JAVA ADA95
Key:
C# major minor 2000
influence influence
COBOL was another early major high-level language. Its most important
contribution was the concept of data descriptions, a forerunner of today’s data
types. Like FORTRAN, COBOL’s control flow was fairly low-level. Also like FORTRAN,
COBOL has developed a long way from its original design, the latest version being
standardized in 2002.
ALGOL60 was the first major programming language to be designed for
communicating algorithms, not just for programming a computer. ALGOL60 intro-
duced the concept of block structure, whereby variables and procedures could
be declared wherever in the program they were needed. It was also the first
major programming language to support recursive procedures. ALGOL60 influ-
enced numerous successor languages so strongly that they are collectively called
ALGOL-like languages.
FORTRAN and ALGOL60 were most useful for numerical computation, and
COBOL for commercial data processing. PL/I was an attempt to design a
general-purpose programming language by merging features from all three. On
8 Chapter 1 Programming languages
top of these it introduced many new features, including low-level forms of excep-
tions and concurrency. The resulting language was huge, complex, incoherent,
and difficult to implement. The PL/I experience showed that simply piling feature
upon feature is a bad way to make a programming language more powerful and
general-purpose.
A better way to gain expressive power is to choose an adequate set of concepts
and allow them to be combined systematically. This was the design philosophy
of ALGOL68. For instance, starting with concepts such as integers, arrays, and
procedures, the ALGOL68 programmer can declare an array of integers, an array of
arrays, or an array of procedures; likewise, the programmer can define a procedure
whose parameter or result is an integer, an array, or another procedure.
PASCAL, however, turned out to be the most popular of the ALGOL-like
languages. It is simple, systematic, and efficiently implementable. PASCAL and
ALGOL68 were among the first major programming languages with both a rich
variety of control structures (conditional and iterative commands) and a rich
variety of data types (such as arrays, records, and recursive types).
C was originally designed to be the system programming language of the UNIX
operating system. The symbiotic relationship between C and UNIX has proved very
good for both of them. C is suitable for writing both low-level code (such as the
UNIX system kernel) and higher-level applications. However, its low-level features
are easily misused, resulting in code that is unportable and unmaintainable.
PASCAL’s powerful successor, ADA, introduced packages and generic units –
designed to aid the construction of large modular programs – as well as high-level
forms of exceptions and concurrency. Like PL/I, ADA was intended by its designers
to become the standard general-purpose programming language. Such a stated
ambition is perhaps very rash, and ADA also attracted a lot of criticism. (For
example, Tony Hoare quipped that PASCAL, like ALGOL60 before it, was a marked
advance on its successors!) The critics were wrong: ADA was very well designed,
is particularly suitable for developing high-quality (reliable, robust, maintainable,
efficient) software, and is the language of choice for mission-critical applications
in fields such as aerospace.
We can discern certain trends in the history of programming languages. One
has been a trend towards higher levels of abstraction. The mnemonics and symbolic
labels of assembly languages abstract away from operation codes and machine
addresses. Variables and assignment abstract away from inspection and updating
of storage locations. Data types abstract away from storage structures. Control
structures abstract away from jumps. Procedures abstract away from subroutines.
Packages achieve encapsulation, and thus improve modularity. Generic units
abstract procedures and packages away from the types of data on which they
operate, and thus improve reusability.
Another trend has been a proliferation of paradigms. Nearly all the languages
mentioned so far have supported imperative programming, which is characterized
by the use of commands and procedures that update variables. PL/I and ADA sup-
port concurrent programming, characterized by the use of concurrent processes.
However, other paradigms have also become popular and important.
1.2 Historical development 9
script that will later be called whenever required. An office system (such as a word
processor or spreadsheet system) might enable the user to store a script (‘‘macro’’)
embodying a common sequence of commands, typically written in VISUAL BASIC.
The Internet has created a variety of new niches for scripting. For example, the
results of a database query might be converted to a dynamic Web page by a script,
typically written in PERL. All these applications are examples of scripting. Scripts
(‘‘programs’’ written in scripting languages) typically are short and high-level, are
developed very quickly, and are used to glue together subsystems written in other
languages. So scripting languages, while having much in common with imperative
programming languages, have different design constraints. The most modern and
best-designed of these scripting languages is PYTHON.
Summary
In this introductory chapter:
• We have seen what is meant by programming linguistics, and the topics encompassed
by this term: concepts and paradigms; syntax, semantics, and pragmatics; and
language processors.
• We have briefly surveyed the history of programming languages. We saw how new
languages inherited successful concepts from their ancestors, and sometimes intro-
duced new concepts of their own. We also saw how the major paradigms evolved:
imperative programming, object-oriented programming, concurrent programming,
functional programming, logic programming, and scripting.
Further reading
Programming language concepts and paradigms are cov- in WEXELBLAT (1980). Comparative studies of program-
ered not only in this book, but also in TENNENT (1981), ming languages may be found in HOROWITZ (1995), PRATT
GHEZZI and JAZAYERI (1997), SEBESTA (2001), and SETHI and ZELCOWITZ (2001), and SEBESTA (2001). A survey
(1996). Programming language syntax and semantics are of scripting languages may be found in BARRON
covered in WATT (1991). Programming language proces- (2000).
sors are covered in AHO et al. (1986), APPEL (1998), and
WATT and BROWN (2000). More detailed information on the programming languages
The early history of programming languages (up to the mentioned in this chapter may be found in the references
1970s) was the theme of a major conference, reported cited in Table 1.1.
Exercises
Note: Harder exercises are marked *.
Programming
language Description
1 Introduction
1.1 The diversity of languages
1.2 The software development process
1.3 Language design
1.4 Languages or systems?
1.5 The lexical elements
Summary
Exercises
Bibliography
2 Historical survey
2.1 Early machines
2.2 Fortran
2.3 Algol
2.4 Business data processing languages
2.5 General or multipurpose languages
2.6 Developing programs interactively
2.7 Special-purpose languages
2.8 Systems programming languages
2.9 Modules, classes and abstract data types
2.10 Functional and logic languages
2.1 1 Conclusions
Summary
Exercises
Bibliography
viii Contents
5 Program structure
5.1 lntroduction
5.2 Procedural and object-oriented architecture
5.3 Alternative program architectures
5.4 Separate compilation
5.5 Larger units
Summary
Exercises
Bibliography
9 Functional languages
9.1 lntroduction
9.2 Lisp
9.3 FP systems
9.4 Modern functional languages
9.5 Concluding remarks
Summary
Exercises
Bibliography
10 Logic programming
10.1 The Prolog approach
10.2 The basics of Prolog
10.3 Data objects
10.4 Efficiency in Prolog
10.5 A Prolog example
10.6 Concluding remarks
Summary
Exercises
Bibliography
c Contents
14 The future
14.1 lntroduction
14.2 Procedural and object-oriented languages
14.3 Declarative languages
14.4 Language design
14.5 Implementation considerations
14.6 Development methods
14.7 Conclusions
Summary
Bibliography
Appendices
1 Language summaries
2 Language texts
Index
Preface to the third edition
In this book we consider the principal programming language concepts and show ho
they are dealt with in object-oriented languages such as Java and Delphi, in tradition
procedural languages such as Pascal, C and Fortran, in hybrid object-oriented or ohjec
based languages such as C++ and Ada 95, in functional languages such as ML and
logic languages like Prolog.
Theprogramminglanguagescenehas always been bedevilledby protagonists pushi
their favourite language. This often leads to a reluctance to examine rival languag
and to a 'love me, love my language' approach. The lack of a scientific approach
languages tends to emphasise the differences between them, even when these are qu
minor. Our approach is to find common ground between languages and to identi
the underlying principles. Although the top-level organisation of a program writt
in an object-oriented language is different from that of one written in a procedur
language, their underlying principles are the same. Similarly, although the approa
.of logic languages and functional languages is different from that of procedural a
object-oriented languages, there are many areas of similarity, and seeing these helps
to understand the differences better.
This approach is important at the present time when there are major and importa
controversies as to which way we should be heading. To what extent is it worthwh
developing new versions of the old faithfuls as has happened with Fortran 90 and Obje
Oriented Cobol? Should we standardise instead on modem object-oriented languag
like Java? It is certainly the case that procedural languages have proved themselv
extremely resilient and have been given a new lease of life by the incorporation
object-oriented features as has happened with C++, Ada 95 and Object Pascal. Wh
is going to be the future position of functional and logic languages? What effect w
new hardware designs and the growth of the Internet have on programming language
Although it is likely that many of these issues will not be resolved for many years, it
xii Preface to the third edition
Intended audience
Although this bookis intended primarily as a student text for a comparative language or
language concepts course, we hope that it will also be read by practising computer pro-
Preface to the third edition x
Chapter 10 Logic programming This deals with logic programming and is mainly
concerned with the language Prolog.
Chapter 11 Concurrency and networking This describes how concurrency ishan-
dled in Ada 95 and Java and how these languages deal with inter-process communi-
cation and synchronisation. Applets, CGI scripts and distributed programming are
then discussed.
Chapter 12 Syntax and semantics This describes how the syntax of programming
languages can be described formally in BNF and outlines two approaches, denota-
tional and axiomatic semantics, for fonndly describing the semantics of program-
ming language constructs.
Chapter 13 Input, output and GUIs This describes both traditional text-basedin-
put and output and the now standard approach of graphical user interfaces.
Chapter 14 The future This reviews the present situation and attempts to predict
the direction in which language design is likely to go.
Appendix 1 Language summaries This summarises the features of the principal
languages dealt with in the text.
Appendix 2 Language texts This gives a11 annotated bibliography for a wide range
of programming languages.
Chapters 1-6 introduce the basic concepts and are best read in the given order, while
Chapters 7-13 build on earlier material and, as they are largely self-contained, can be
takenin any order. Each chapter contains a synopsis, outlining the major topics to be
covered, a concise end-of-chapter summary, exercises and an annotated bibliography.
Solutions to selected exercises arc given at thc end of the hook.
Finally we should make clear what this book is not. It is not a language reference
manual or a text on language implementation. We make no attempt to teach any pastic-
ular language, but the annotated bibliography at the end of the book gives suggestions
for further reading in all the languages covered. It is also not a book on the principles of
program construction, although throughout the book we view each language construct
from the point of view of whether or not it helps or hinders the construction of readable
and reliable programs.
Acknowledgements
We would like to thank colleagues in the Computing Science Department at the Uni-
versity of Stirling, in particular Alan Hamilton, Simon Jones, Sam Nelson, Charles
Rattray and Leslie Smith. They have acted as an ideal sounding board and their helpful
criticisms of various chapter drafts have prevented us from straying too far into error.
In addition, we would like to thank Kate Brewin of Pearson Education for her help
and encouragement.
Robert Clark
Stirling, June 2000
Introduction
1.1 The diversity of languages
1.2 The software development process
1.3 Language design
1.4 Languages or systems?
1.5 The lexical elements
maintenance
Development models
It is important to realise that the software development process is iterative, not seque
tial. Therefore, knowledge gained at any one of the stages outlined can (and should) b
used to give feedback to earlier stages. The traditional approach is to treat the differe
stages in thedevelopmentprocess as being self-contained and this has led to the waterfa
model of software development shown in Figure 1.1.
However, there has been increasing acceptance of the idea that an incremental an
iterative approach is much more realistic. Central to this approach is the idea of ris
management. Every time we make a decision, there is the possibility that we get
wrong. Wetherefore wantto have continual feedhackto show up possible errors becau
the longer an error remains undetected, the more expensive it will be to put right. Th
led to the spiral model shown in Figure 1.2 (Boehm, 1988). We start at the centre of th
spiral and go repeatedly through the different stages as our systemis built incrementall
Many modem languages are object-oriented and this has led to the creation
object-oriented development methods. In other development methods, there is a cle
distinction in the techniques used in specification, design and implementation. Howeve
in object-oriented development, a problem can be understood and a solution designe
and then implemented using the same framework of a set of communicating objec
The object-oriented development process is therefore well suited to an incremental an
iterative approach. At any given stage, different objects can be described at differe
levels of abstraction. As the iterative development process continues, we incremental
add more detail to the object descriptions.
The need for a notation in which a specification or design can he written dow
Introduction
has led to the development of both specification and program design languages. Such
languages are at a higher level of abstraction and give fewer details than implementation
languages. Many specification languages are mathematical in form and are amenable to
prooftechniques. However, languages of this type are outside the scope of this book and
so we only look at what are conventionally considered to be implementation languages,
although some functional languages have been used as executable specification lan-
guages.
Another approach is to use graphical notations to capture the requirements and
represent designs. Examples of diagrams that occur in many different development
methods are data flow diagrams, entity relationship diagrams, state transition diagrams
and message sequence charts. A problem is that each development method can use its
own set of diagram notations which, although they arerepresentingmuchthe same thing,
can differ in detail. This situation is far from satisfactory as it can suggest differences
in the development process that do not really exist. In object-oriented development,
a standard notation called the Unified Modeling Language (UML) has been adopted
so that different methods now use a common notation (Booch et al., 1998). There are
several different kinds of diagram in UML, but the single most important is the class
diagram which shows the classes involved in an object system and their associations.
An example class diagram is shown in Chapter 8.
The use of a systematic software development process has greatly influenced both
language design and how languages are used. For example, Pascal was designed to
support the ideas of structured programming. The problems of constructing large
systems and of program maintenance led to the introduction of language feahues that
allow large systems to be broken down into self-contained modules. Packages in Ada
and classes in object-oriented languages satisfy that need. It is clear, therefore, that
programming languages do not exist in a vacuum; rather, the design of modern languages
is a direct response to the needs and problems of the software development process.
Language design
a
Language design
Most widely used programming languages are imperative; examples are Fortra
COBOL, C, C++, Pascal, Ada and Java. A program written in an imperative langua
achieves its effect by changing the value of variables or the attributes of objects b
means of assignment statements. Until quite recently, most widely used imperati
languages were procedural, that is their organisation was centred around the definiti
of procedures. Many .procedural languages have now been extended to include objec
nrientedfeatures (C by C++, Pascal by Delphi, Adaby Ada95, COBOLby OOCOBO
Basic by Visual Basic) while other neW.purely object-oriented languages such as Eif
and Java have been designed. Object-oriented programs are organised as a set of objec
which communicate with one another through small strictly defined interfaces.
Other approaches to language design include functional languages (such as pu
Lisp and ML) and logic languages (such as Prolog). These alternative approaches a
dealt with in Chapters 9 and 10 respectively.
The p r i m q purpose of a programming language is to support the constmcti
of reliable software. Hence, in most modem languages, type checking takes place
compile time, which is a considerable help in catching logical errors before the progra
is run. It is also important that a language is user friendly so that it is straightforward
design, write, read, test, m, document and modify programs written in that languag
To understand how these objectives may be achieved, the issues of language desig
can be divided into several broad categories:
expressive power,
slmpl~cityand orthogonality,
implementation,
a error detection and correction.
"correctness and standards
Expressive power
A programming language with high expressive power enables solutions to be express
in terms of the problem being solved rather than in terms of the computer on whi
the solution is to be implemented. Hence, the programmer can concentrate on proble
solving. Such a language should provide a convenient notation to describe both alg
rithms and data stmctures in addition to supporting the ideas of structured programmin
and modularisation.
Another aspect of expressive power is the number of types provided together wi
their associated operations. Instead of providing a large number of built-in types, mo
modem languages provide facilities, such as the Adapackage or the C++ and Java cla
for defining new types, called abstract data types. Such languages can then provide
wide range of predefined types by means of standard libraries which the programm
can use to build new types for the problem in hand. When a language, together wi
its standard libraries, does not include a suitable range of types and operations, th
the programmer generally has to provide these by declarations, thereby distracti
5 Introduction
the programmer's attention to the lower level aspects of solving the problem. Often,
languages may have high expressive power in some areas, but not in others; for example,
Ada has a range of numerical operations that give it expressive power for numerical
work, but it is less effective in data processing applications.
Also included under the heading of expressive power is readability; that is, the ease
with which someone familiar with the language can read and understand programs
written by other people. Readability is considerably enhanced by a well-designed
comment facility, and good layout and naming conventions. In practice, it should be
possible to write programs that can act, to anextent, as their own documentation, thereby
making maintenance and extension of the pregram much easier.
object. We therefore have the same syntax meaning different things. Although this i
inconsistent, it can be argued that inventing new syntax to make the distinction clea
would have just complicated matters.
Implementation
Execution of a program written in an imperative language, such as Pascal, Ada or C++
normally takes place by translating (compiling) the source program into an equivalen
machine code program. This machine code program is then executed. The ease wit
which a language can be translated m d the efficiency of the resulting code can b
major factors in a language's success. Large languages, for example, have an inheren
disadvantage in this respect because the compiler will, almost inevitably, be large, slo
and expensive.
An alternative to compiling a source program is to use an interpreter. An interprete
can directly execute a source program, hut what is more commonis for a source program
to be translated into some intermediate form which is then executed by the interprete
The interpreter can be said to implement a virtual machine. Executing a program
under the control of an interpreter is much slower than running the equivalent machin
code program, but does give much more flexibility at rnn time. The added flexibili
is important in languages whose main purpose is symbolic manipulation rather tha
numerical calculation. Examples of such languages are the string processing languag
SNOBOL4, the object-oriented language Smalltalk, the functional language Lisp, th
logic language Prolog and the scripting language Perl.
The use of an interpreter also supports an interactive programming environmen
in which programs may be developed incrementally. When developing a Lisp program
for example, a programmer can interact directly with the Lisp interpreter and type
the definition of functions followed by expressions which call these functions. Th
expressions are immediately executed and the results made available. This allows th
early detection, and easy correction, of logical errors. Once the complete program ha
been developed, it can be compiled so that it will run faster.
Java is an imperative language and so we would expect that it would normal
he compiled into machine code. However, that is not the case; Java programs a
interpreted. An exciting use of Java is to animate web pages. A person can download
.web page which contains a Java applet (a small application) and, using a Java-enable
web browser such as Netscape or Internet Explorer, can run the applet. To achieve thi
it must he possible for a Java program to be translated on one computer and to ru
on a different kind of computer and the easiest way of doing this is to translate Jav
source programs into code for a Java virtual machine. Java-enabled browsers provid
interpreters for the Java virtual machine.
Some language designers, notably Wirth the designer of Pascal and Modula-2, hav
made many of their design decisions on the basis of the ease with which a feature ca
be compiled and executed efficiently. One of the many advantages of having a clo
working relationship between the language design and language implementation team
is that the designers can obtain early feedback on constructs that are causing troubl
Often, features that are difficult to translate are also difficult for human programme
to understand. Algol 68 is a prime example of a language that had a lack of success du
B Introduction
to the fact that it was designed by a committee who largely ignored inlplementation
considerations, as they felt that such considerations would restrict the ability to produce
a powerful language. In contrast, the implementation of C, C++, Pascal ;md Java went
hand in hand with their design and the Ada design team was dominated by language
implementers.
However, it is necessary to achieve a proper balance between the introduction of
powerful new features and their ease of implementation. I S 0 Standard Pascal, for
example, has features, such as procedures being able to accept array parameters of
differing lengths, which were omitted from the original version of the language on the
grounds that they were too expensive to implement.
An impoaant feature of programs that use graphical user interfaces is that they are
event driven. They wait for some user event such as the click of a mouse over the
representation of a button on the screen, handle that event and then wait for the next
user event to occur. This leads to a very different program structure from that provided
by traditional programming languages. Writing event driven programs is difficult, but is
dealt with in languages such as Java, Visual Basic and Delphi by most of the work being
done behind the scenes. This allows the programmer to work at a very high level of
abstraction and not worry about implementation details. With earlier languages, event
handling had to be explicitly programmed. This is therefore another example of where
the distinction between a language and its supporting environment has become blurred.
Character set
The character set can be thought of as containing the basic building blocks of a pro-
gramming language - letters, digits and special characters such as arithmetic operators
and punctuation symbols. Two different approaches were taken when deciding the
character set to be used in early languages. One is to choose all the characters deemed
necessary. This is the approach taken with APL and Algol 60, but it has the drawback
that either special input/output equipment has to be used or changes have to be made
to the published language when it is used on a computer.
The other approach is to use only the characters commonly available with current
input and output devices. Hence, the character set of early versions of Fortran was
restricted by the 64 characters available with punched cards while Pascal initially was
constrained by the character set available with the CDC 6000 series computer on which
it was first implemented.
Since the early 1970s, most input and output devices have supported internationally
accepted character sets such as ASCII (American Standard Code for Information
Interchange) and this has been reflected in the character sets of languages. The ASCII
character set has 128 characters of which 95 are printable; the remaining characters are
special control characters. The printable characters are the upper and lower case letters,
digits, punctuation characters, arithmetic operators and three different sets of brackets
0,[I and 1). Composite symbols are used to extend the range of symbols available.
Commonly used examples are the relational operators <= and >= and the assignment
operator :=used in the Algol family of languages.
More recently, the Unicode character set has been created to give a much larger
range of characters. Each Unicode character occupies 16 bits rather than the 8 used
with ASCII characters. Java uses the Unicode character set.
The lexical elements 1
Comments
Almost all languages allow comments, thereby making the program more readi
understood by the human reader. Such comments are, however, ignored by the compile
In early languages such as Fortran, which has a fixed format of one statement per lin
12 Introduction
comments are terminated by the end of a line. In Fortran's case, the comment lines were
started by a C in column 1. A similar method is used in other early languages such as
COBOL and SNOBOU.
Algol 60 uses a different method for comments: they begin with the reserved word
connnent and terminate with a semi-colon. However, the problem with this method is
that programmers often fail to terminate comments correctly. Consequently, the com-
piler, interpreting the program exactly, incorporates the next declaration or statement
into the comment. Errors caused in this way are difficult to find as the error message, if
one is generated, is usually quite unrelated to the actual error.
Most later languages enclose comments iff brackets. Pascal, for example, uses either
( * and * ) or [ and ] while C uses / * and * / . But this approach still leaves the problem
of terminating a comment unresolved. Some compilers alleviate this problem by giving
a warning if a statement separator - that is, a semi-colon - occurs within a comment.
Ada, in contrast, commences a comment wilh two hyphens and ends it by the end of
a line, so reverting to the methods of the earliest high-level languages. In C++ and
Java, the programmer can either use C style comments or start a comment by / / and
terminate it by the end of a line.
The problem of failing to properly terminats acomment is largely solved by integrated
development environments (IDES) which automatically colour-code different parts of
the program. When a comment is in a different colour, it is obvious when it has not
been properly terminated.
Summary
( Bibliography )
The approach taken in this book to focus op language concepts and show how these
concepts are realised in different programming languages is similar to that adopted by
Ghezzi and Jazayeri (1997) and Sebesta (1998). The hook by Sethi (1996) also takes
this approach, but is more theoretical.
The alternative approach of having separate chapters on the main programming
languages has been adopted by MacLennan (1987) and Friedman (1991). Pratt and
Zelkowitz (1996), on the other hand, has combined both approaches: the language
features are discussed in the first part of the book while the second part is devoted to
individual languages. The result is comprehensive, although it leads to a very large
text. Both F'ratt and MacLennan also contain a large amount of material on language
implementation.
Boehm, B.W. (1988). 'A Spiral Mode1 of Software Development and Enhancement'
Computer, 21(5), 61-72.
Booch, G., Rumhaugh, J. and Jacobson, I. (1998). The Un$ied Modeling Language
User Guide. Addison-Wesley.
Friedman, L.W. (1991). Comparative Programming Languages. Prentice-Hall.
Ghezzi, C . and Jazayeri, M. (1997). Programming Language Concepts (Third Edition).
John Wiley & Sons.
MacLennan, B.J. (1987). Principles of Programming Languages (Second Edition).
Holt, Rinehart and Winston.
F'ratt, T.W. and Zelkowitz,M. (1996). Programming Languages: Design andlmplement-
atidn (Third Edition). Prentice-Hall.
Sebesta, R. (1998). Concepts of Programming Languages (Fourth Edition). Addison-
Wesley.
Sethi, R. (1996). Programming Languages (Second Edition). Addison-Wesley.
Wirth, N. (1975). 'On the Design of Programming Languages', Z F I P 74, pp. 386-393,
North-Holland.
Historical survey
2.1 Early machines
2.2 Fortran
2.3 Algol
2.4 Business data processing languages
2.5 General or multipurpose languages
2.6 Developing programs interactively
2.7 Special-purpose languages
2.8 Systems programming languages
2.9 Modules, classes and abstract data types
2.10 Functional and logic languages
2.1 1 Conclusions
There are two main reasons for studying the history of programming languages. Firstl
the languages available today are only explicable by examining how they grew up. On
has to look at their development to understand why, for example, two of the majo
languages, Fortran and COBOL, are still in use 40 years after their first appearanc
There is in fact a huge inertia in the programming field, which means that once
language has been successful, it is very difficult to supersede it by a newer languag
The large investment in established systems ensures the continuing use of o
languages.
The second reason for looking at the history of programming languages is to pinpoin
some of the errors made in the past and so try to avoid repeating them. A prime examp
where this was not the case was the early development of microprocessor systems whic
paralleled that of the early computers in many respects. Unfortunately, many of the sam
mistakes were repeated because the software designers were unaware of the historic
lessons.
16 Historical survey
This chapter starts its survey from the languages used with the early computers and
traces their development to Ada 95, Prolog, C++, ML and lava. While every attempt has
been made to be historically accurate, the main purpose of this survey is to give the
flavour of programming language development and to try to recapture the feelings of
programmers at the time when each new language arrived on the scene.
(21Early machines
The birth of programming languages is a matl%rforsome conjecture. Some people might
consider that Ada, Countess of Lovelace, was the first programmer because she worked
with Charles Bahbage on the Analytical Engine. However, such academic speculations
are best left to the historians. Likewise, the early work on the machines and languages
of the late 1940s is of little interest in the development of high-level programming
languages.
The early languages, called order codes or instruction codes, were in fact very
primitive, even in comparison with assemblers. They used numbers, not only for store
locations and the special registers (called accumulators) of the central processing unit
(CPU), but also for operation codes. Often, there were no mnemonics or floating point,
and library routines, which were used for routine calculations and for input and output,
were not called, but were inserted in the code. Also, loops, in which the instructions
could be changed, were far from the modern f o r loop in ease of operation although
their-purpose was the same.
Although order codes with mnemonics were used on machines such as the EDSAC I,
programming at this level was soon seen to be a considerable drawback in the advance
of computers. Machine codes were both hard to learn and difficult to use, which meant
that early programs were full of errors and the 'patch' - that is, actually changing the
executable code - was the standard method of correction. However, the middle and late
1950s saw a surge in the attempt to improve programming languages on both sides of
the Atlantic.
(zz) Fortran
The birth of Fortran
The big breakthroughin the early years was 'The IBMMathematical FORmulaTRANs-
lating system', known then and subsequently as Fortran. This was by no means an
isolated development, but depended very much on the previous attempts to raise the
level of programming languages. The manual for Fortran I was released in 1956, but
it was 1958 before successful compilers were running programs correctly. After this,
Fortran took off in a manner that probably surprised even its most ardent advocates.
Oneof the principal designers of Fortran, Backus, has madeit clear that themotivating
factor behind the language was not the beauty of programming in a mathematical no-
tation hut the economics of programming at that time (Wexelblat, 1981). Programming
and debugging costs exceeded running costs and the situation was worsening with the
Fortran 1
advent of faster computers. The only solution was to design a language for scientifi
computations that allowed the programmer to use mathematical notation. However
the designers of Fortran felt that this had to be done in a way that produced efficien
object code, otherwise practising programmers would reject the language if they could
produce a hand-coded version that ran much faster than the compiled Fortran program
Such worries have left their mark on Fortran and considerations of run-time efficienc
played a major role in its design, as did the IBM 704 machine and its punched card
input.
Since Fortran was designed primarily for scientific calculations, string handling
facilities were almost non-existent andthe only data structure was the array. Although
the array was hedged about with limitations, it did represent a considerable step forward
Other Fortran features that were attractive to its new devotees were:
Comments.
Assignment statements that allowed mathematical expressions of some complexity
on the 'right-hand' side.
The simplicity of writing loops with the DO statement.
Subroutines and functions: the idea of the subroutine and function was not new, bu
Foruan did improve on them by employing a symbolic notation close to mathemat
ics.
Formats for input and output: input and output conversions were notoriously difficu
on early computers, but Fortran formatting took a lot of the pain away.
Machine independence: a Fortran program could be run on different machines
Considering the lack of experience of compiling in the late 1950s, the early Fortra
compilers were remarkably good; but even so they were unable to achieve the aim o
their designers, which was to produce code that was as efficient as hand-coded versions
Despite this, Fortran became enormously popular in a very short time, the main reason
for its success being:
A Fortran program
The following program finds the mean of a list of numbers and the number of value
that are greater than the mean.
18 Historical survey
Notes
1. The first two lines are comments.
2. In the third line, the array has to be declared and its size given; in this case 99
elements with subscripts from 1 to 99. (The Algol 60 program later in this section
shows the use of an array with variable bounds.)
3. Most Fortran variables are declared implicitly by use. However, MEAN is declared
explicitly as REAL because if it was declared implicitly, it would be an INTEGER
variable, as its first letter is between I and N.
I
Fortran II
Fortran 90
Fortran 90 supports many new features: allocation of space for arrays on block entry
records, modules, pointers, etc., but to protect the huge investment in existing Fortran
programs, all legal Fortran 77 programs are also legal inFortran 90. This means that the
language is a mixture of old and new features, although some old features are labelled
as obsolescent with the intention that their use will wither away so that they can be
removed from the next standard. The development of Fortran and associated languages
is shown in Figure 2.1.
a
Algol
The period of the late 1950s was a very important one in the history of programming
languages. Not only did it see the development of Fortran and COBOL but also a third
major language - namely, Algol. No other language has had such a profound influenc
on programming language design and definition as that of Algol.
Algol emerged from a joint committee of European and American programming
language experts that was set up with the aim of producing a common language
(Wexelblat, 1981). Originally, this language was called IAL (International Algebraic
Language) but later it became known as Algol (ALGOrithmic Language). The objective
of the language were stated as follows:
The committee's first product, usually known as Algol 58, was never implemented
but the criticisms raised did help in the development of a subsequent version, Algol 60
The 'Report on the Algorithmic Language ALGOL 60' (Naur et al., 1960) was a majo
20 Historical survey
event in the history of programming languages and the 'Revised Report' (Naur et al.,
1963), published three years later, is a classic. It may seem surprising to make such a
song and dance about a language that was never in widespread use in thc United States.
However, its influence has been greater than that of Fortran and no other language has
added so much to programming language theory.
The major concepts introduced by Algol 60 were:
Language definition: a formal language (BNF) was used to define thz syntax for the
first time, a concept that led naturally to syntax-directed compilers. The semantics,
however, proved more difficult and % definitions in English did lead to some
ambiguity.
, . Algol 60 was structured: it was the original block-structured language and variables
were not visible outside the block in which they were declared.
Arrays could have variable bounds at compile time, although the bounds had to be
fixed when the block, in which the array was declared, was entered at run time so
that suitable storage could be allocated.
Algol 60 contained several structuredcontrol statements. The ifstatement and f o r
statement were considerable advances on similar constructs in Fortran although the
Algol 60 control statements were simplified in later Algol-like languages.
:.. Algol 60 was the first language to introduce recursive procedures. However, there
was some argument as to whether the original committee realised the full import of
their proposals in this area. Originally, recursion was decricd as 'academic' and of
little practical utility. But this view was partly caused by the difficulties the early
Algol 60 compilers had in implementing the concept. However, there is no doubt
now that the ability to use recursion is a very important programming skill and with
improved compilers it is not inefficient.
As already indicated, Algol 60 was intended as a reference and publication language
as well as a language for writing programs to mn on computers. This led to its use
by, amongst others, the Association for Computing Machinery (ACM) to communicate
algorithms between users. But despite its powerful and improved facilities, Algol 60
was unable to supersede Fortran as the main scientific language. Several reasons have
been advanced for this, hut it was probably a combination of factors that kept Fortran
well ahead, namely:
Since Algol 60 compilers came out approximately three years after Fortran, the
latter was strongly entrenched and programmers were reluctant to change. This was
the first @ut not last) instance of a new language being unable to supersede an
established competitor.
Since Algol 60 had more features, it was harder to learn.
: Although IBM initially supported Algol 60, they eventually decided that its cus-
tomers were happy with Fortran and so did not wish to change. The great success
of IBM in the 1960s helped to boost Fortran.
Fortran compllers were sunpler and produced more efficient code than Algol 60
compllers
Algol 21
Algol 60 had no official input/output (UO). It was decided to leave this to the
individual manufacturer$ so that they could tailor it to their computers. Although
this seemed a reasonable decision, if a semi-official standard 110 had been agreed
then many manufacturers would have used it and a de facto standard Algol 60 would
have been formulated.
An Algol 60 program
The following Algol 60 program solves the problem of findlng the mean of a l ~ s ot f
numbers and how many numbers are gaater than the mean.
begin
comment this program finds the mean of n numbers
and the number of values greater than the mean;
integer n;
readin);
begin
real array a [l:nl ;
integer i, number;
real sum, mean;
for i := 1 step 1 until n do
read (a[il);
sum : = 0.0;
for i : = 1 step 1 until n do
sum : = sum + alil;
mean : = sum / n;
number : = 0;
for i : = 1 step 1 until n do
if a[il > mean then
number : = number + 1;
write ("MEAN= " , mean, "NUMBER OVER MEAN = " , number)
end
end
Notes
1. Unlike Fortran, the array declarations in Algol 60 could have variable bounds, a
the array a has in this program. Variable bounded arrays can only he declared in an
inner block and the value of the variable bound must be known before the block i
entered at run time.
2. There are no implicit declarations in Algol 60 -all variables must be declared.
Algol 60
I
Oberon
Java
and Hoare, 1966). In essence, this represented a tidying up of Algol 60 with several
important new features. The most important changes and additions were:
Records and references: they provided data structures other than arrays and allowed
linked hsts, trees and graphs.
The case statement
Changes which separated the f o r and while statements and made the f o r
statement more reqtr~ctedand less prone to error
Procedure and function parameters could be called by value, result and value-
result. The call-by-name method of parameter passing introduced by Algol 60
used the obvious mathematical approach of replacing a formal parameter by the
corresponding actual parameter wherever it occurred. However, this method had
been found to he inefficient and in some instances it led to unexpected results.
Although it was still available in Algol W, it was discouraged.
Long real and complex data types were introduced to enable double-length
and complex arithmetic.
': The b i t s data type gave low-level processing ability.
Some string facilities were included, but they were still very primitive
Assert statements were allowed and the assertions tested during aprogram run
Algol W was indeed a worthy successor to Algol 60 and, although not widely
available, it was well liked by its users.
The next Algol-like language was Algol 68, which was produced amid much contro-
versy by the International Federation for Information Processing (LFIP) Algol working
party in 1968. Its initial specification was so abstruse that there was some delay in its
implementation and simple guides were produced before even partial acceptance of the
language was achieved. Although Algol 68 had many virtues, these were rather lost in
the controversy about its specification (Bergin and Gibson, 1996).
Consequently, the large claims made for Algol 68 were never achieved. The idea of
it being a universal language and ideally suited for data processing applications may
have had some validity, but this made little impact on practising programmers.
Algol 2
An economy of constmcts: the idea was to produce a core language with a sma
number of powerful constructs. (Note that PLiI, which is discussed in Section 2.5
went the other way by trying to be a comprehensive language.)
Orthogonality: this was a major design goal of Algol 68. Having determined how
a feature worked in one situation, it could be expected to behave in a similar wa
in any other situation; that is, there were no interactions between constructs whe
they were combined.
*.
Pascal
Pascal was developed by Niklaus Wirth in the late 1960s and early 1970s buildin
on his earlier work with Algol W. His aims were to produce a language that could b
efficiently implemented on most computers andbe suitable for teaching programming a
a logical and systematic discipline, thus encouraging well-structured and well-organise
programs. Although Pascal is a direct descendant of Algol 60, there was a determine
effort by Wirth to make his language efficient. He felt that this was the only way
challenge the strong grip Fortran had on programming, particularly in theunited State
Thus, Pascal contains certain features for efficiency reasons.
The static array is probably the most controversial feature of Pascal. In most Algo
like languages, the size of an array does not have to he specified until a block is entere
at run time. Although this allows for more flexible programming and a more efficie
use of storage, it does usually slow down program execution. Pascal adopted the stat
array, as used in Fortran, where the size is determined at compile time. In additio
the passing of array parameters in procedures also used fixed sized arrays. This was a
even more controversial decision because of the restrictions it imposed, particularly o
those doing numerical calculations. However, this restriction was removed when th
I S 0 Standard for Pascal was published in 1982 (ISO, 1982).
One of the positive aspects of Pascal is the inclusion of features that encourag
well-written and well-structured programs. For example, although goto statemen
are included, they are a restricted and minor feature of the language. Data types are
prominent feature of Pascal and they can be built up from the primitive, unstructure
types Integer,R e a l , Boolean, Char andenumeration types. The structureduse
defined types include arrays, records, sets and files. In addition, pointer types may b
used, usually in conjunction with records, to form linked lists or trees. Strings can b
declared and manipulated in Pascal, but the rigid size of the string and the lack
suitable string operations make string handling clumsy.
Pascal became widely used in the late 1970s when many universities adopted it
their initial teaching language for computer science students and by the mid-1980s
had become the dominant teaching language. The reasons for this movement were th
need for a language that provided a comprehensive set of data structures and whic
encouraged good programming style.
Many implementations of Pascal have added modules, leading to incompatible exte
sions to the language. As well as being a widely used language in its own right, Pasc
has been very influential in the design of later programming languages. Wirth's ne
24 Historical survey
language was Modula, followed by Modula-2. Both were developed from Pascal and,
as the names suggest, the main extension was modules. It also provided a foundation
for the design of Ada while Delphi includes an object-oriented Pascal. We return to the
topic of modules in Section 2.8.
COBOL
COBOL (Common Business Oriented Language) was yet another important language
developed in the late 1950s. Its development was co-ordinated by a committee consisting
mainly of representatives of computer manufacturers in the United States. Although the
major influence on the design of COBOL was FLOW-MATIC, other earlier languages,
notably CommercialTranslator andAIMAC0, also hadsome effect. COBOL was in fact
a development from previous languages and ideas rather than a designed language. Its
use has been widespread and for many years it was the single most-used programming
language in the world. Undoubtedly, the policy of the US Department of Defense
(DOD), wbich was strongly influenced by Grace Hopper, had a considerable effect
on the success of COBOL. Apart from being one of the prime protagonists of the
early meetings and committees when COBOL was introduced, the Department made
it its policy to award contracts only where a COBOL compiler was available, and all
computers purchased with Government funds had to have such a compiler. In fact, the
DOD made COBOL a defacto standard long before 1968 when its standard definition
was published.
Since COBOL is essentially a data processing language, it differs significantly from
Fortran and Algol, wbich emerged at about the same time. It places considerable
emphasis on data and file processing, while keeping language features necessary for
calculations very simple. As the language statements have an English-like syntax,
COBOL is verbose. This was a deliberate design feature, its intention being that
Business data processing languages 25
managers as well as programmers would find the final programs readable. The verbosity
does cause some experienced programmers anguish and attempts were made, via
systems like Rapidwrite (Humby, 1964), to allow a shorthand version of COBOL to be
written by the professional programmer, from which the compiler could produce ful
COBOL.
While COBOL was never intended as an innovative language - indeed, it has had
very little influence on subsequent languages - it did introduce the basic idea o
distinguishing between the description of the data, the physical environment in which
the computing was to he done and the actual processes performed on the data. Thus, th
logical description of the data of the pmblem could be described independently of th
physical characteristics of the media on which it was stored and manipulated; that is
the description is machine independent without being too inefficient. This separation i
an important feature of COBOL and represented a major advance in its time.
A COBOL program is divided into four parts:
1. The identification division, which provides commentary and program documenta
tion.
2. The environment division, which contains machine-dependent program specifica
tions. Thus, it specifies the connections between the COBOL program and th
external data files.
3. The data division, which gives a logical description of the data.
4. The procedure division, which contains the algorithms necessary to solve the prob
lem.
Not all of the design features of COBOL have proved successful. For example, few
programmers consider that the English-like form of the COBOL statement makes th
overall program easily comprehensible. The difficulties of readability was compounde
by the lack of structured statements, although this has been rectified in later versions.
PL/I
In the early 1960s, two categories of programmer were fairly clearly distinguished
On the one hand, there was the scientific programmer, usually using Fortran, whos
needs were floating-point arithmetic, arrays, procedures and fast computation, usually
via hatch job processing. On the other hand, there was the commercial user who merely
required decimal arithmetic, but who also required fast and asynchronous inputloutput
string handling facilities and efficient searching and sorting routines. However, ther
was also a growing band of special-purpose users who had diverse requirements, suc
as efficient real-time working, string @attern matching facilities, low-level system
programming and list processing.
LBM was very much in the forefront of progress at this time and saw the opportunity
in providing a computer system suitable for a wide range of users. The computer tha
emerged was the IBM 360. Together with the new hardware, a new programming
language was to be developed. It was originally called NPL, but that acronym was late
dropped in favour of PLA (Programming Language I) because of confusion with th
National Physical Laboratory at Teddington, UK.
The new programming language was originally designed by a committee of IBM an
their users who solicited views from a wide range of people as well as studying th
major current languages Fortran, Algol, COBOL and JOVIAL. The guiding principle
of the designers were as follows:
@ programmers' time is an important asset and should not be wasted,
?!' there is a unity in programming which the current division between scientific an
commercial languages did not reflect.
The designers hoped, therefore, to produce a language that was comprehensive, eas
to learn, teach and use, and capable of extension and subsetting. There were to be as few
machine dependencies as possible while allowing the programmer to have full access t
machine and operating system facilities without resorting to assembly language coding
To accomplish all these design criteria, a large language was obviously going t
be required. However, the designers felt that the programmers need not know all th
features of the language to be able to use it efficiently. The result was the crucial an
controversial idea at the heart of PLII - namely, default. Every attribute of a variable
every option and every specification bad a default interpretation and this was set to b
the one most likely to be required by a programmer who does not know that alternative
exist.
PL/I combined ideas from Fortran, Algol and COBOL. From Fortran, came th
parameter passing mechanisms, independently compiled subprograms, formatted in
putloutput and COMMON blocks; from Algol, block structure and structured statement
from COBOL, record inputloutput, PICTURE type declarations and heterogeneous dat
structures. There were, however, ideas culled from elsewhere; namely, list-processin
concepts, control structures and methods for storage management. One new feature wa
exception handling by means of ON-conditions.
Before PLA, language designers had either opted for run-time efficiency at th
expense of flexibility (as was done, for example, in Fortran and COBOL) or else ha
allowed flexibility at the expense of run-time inefficiency (for example, SNOBOL an
28 Historical survey
Lisp). PL/I, incontrast, attempted to have bothrun-time efficiency and flexibility,but the
penalty it paid was language complexity. It did, by its existence, highlight the problems
in trying to design a general-purpose language that tries to satisfy all programmers.
Nevertheless, it represents one extreme in designphilosophy; that is, providing featutures
for all applications within a fixed framework - what might be called a 'complete'
language.
An alternative strategy to PL/I, represented by Algol 68, was to have a small core
of language features that could be combined to form more complex structures. The
argument of core versus complete languages was much debated in the late 1960s and
early 1970s but no worthwhile conclusionsrwere reached. Object-oriented languages,
which can have a small core coupled with the ability to extend existing and to define
new types, can claim to provide the answer to this problem.
A PL/I program
Here is a PL/I solution to the problem of finding the mean of a list of numbers and the
number of values that are greater than the mean:
Notes
1. PL/I allows both explicit and implicit declarations which can include initialisation
as in the case of SUM and NUMBER above.
3. The final END can be used to terminate any inner blocks as well as the outermost
block.
Developing programs interactively 2
Early computers only ran one program at a time, but as computers developed an
became more complex, operating systems were designed to use the available facilitie
h i g h speed store, backing store, input/output devices - more efficiently. For example
the slowness of the inputloutput operations in comparison with the speed of the centra
processor led to time sharing, with many remote stations sharing the time of the centra
computer. Eventually, the remote terminal became the normal tool of the programme
Changes such as these started in the early 1960s and gradually gathered momentum
until by the mid-1970s it was commonplace.
Although programming languages began to adapt to these changing circumstances
the provisions varied widely. Most language compilers are available to programmers a
their terminals or workstations in more or less the same way as that for batchprocessing
Programmers put their programs into a file and then run the appropriate languag
compiler using the file as the source program. Errors, if there are any, are output t
the terminal and, if necessary, placed in a file for reference. The programmer can the
modify the original file and re-mn the compiler. That is still how programs in mos
current languages are developed.
Some languages, for example functional and logic languages, are designed so tha
their programs are normally developed interactively. There have also been attempts t
provide procedural programmers with facilities for developing programs interactively
JOSS (Johnniac Open Shop System), developed in the early 1960s at the RA*
Corporation, was probably the first interactive language. It demonstrated the valu
of on-line access to a computer and provided simple calculating facilities, a featur
that was particularly useful to non-specialist engineers. QUIKTRAN, which emerge
a little later, was the result of an attempt to adapt an existing language, Fortran, fo
use on a remote terminal: features of Fortran that were unsuitable for an interactiv
environment were omitted while anumber of features that facilitated on-line debuggin
30 Historical survey
were added. QUIKTRAN was kept compatible with Fortran so that programs developed
and debugged on a terminal could also use the regular Fortran compiler in batch mode.
However, it is the interactive language Basic that has had most impact on program-
ming.
Basic
Basic (Beginner's All Purpose Symbolic Instruction Code) was developed at Dartmouth
College by Kemeny and Kurtz in the mid-1960s. Their intention was to produce a
language that was very simple for students to learn 'and one that was easy to translate.
The idea was that students could be merely casual users or go on from Basic to more
sophisticated and powerful languages, and that a casual programmer who has done
nothing for six months can still remember how to program in Basic (JOSS also claims
this benefit). As someone described it, it is like learning to ride a bicycle or swim: once
learned never forgotten. For many programmers, Basic was like a return to the early
autocodes: it could be learnt very quickly and programs written after one or two day's
practice. However, it was not without its problems, particularly with large programs.
Like Fortran a decade earlier, the success of Basic surprised its inventors. However,
this success was, no doubt, due mainly to the need for a simple high-level language for
the new microcomputers of the mid-1970s, and Basic was available, well known and
certainly simple. It caught on in a big way.
In addition to the normal statements of a traditional programming language, Basic
has a few simple user commands which represent the interactive part of the language.
The NEW command is used to create a Basic program, which may be listed by the L I S T
command, executed by the RUN conunand and saved by the SAVE command. Any
previously saved program can be retrieved for further use by the OLD command. Basic
is therefore not just a language, but incorporates sufficient operating system commands
to make it complete in itself.
A Basic program
The solution to the problem of finding the mean and the number of values greater than
the mean is given here in Basic for comparison:
130 NEXT I
140 PRINT "MEAN IS", MEAN
150 PRINT "NUMBER GREATER THAN MEAN I S " , K
160 STOP
170 END
Note
1.Variables cannot be declared, are s j g l e letters and automatically initialise to zero
The variable S does not therefore have to be given an initial value.
Basic continues to be widely used and many dialects have been developed, mos
of which add more structure to the language. An object-oriented extension to Basi
is the underlying language of Visual Basic which is widely used in the production o
applications requiring graphical user interfaces on Microsoft Windows systems.
APL
APL (A Programming Language) was originally defined by Iverson as a mathematica
language for the concise description of numerical algorithms. In its original form, i
contained a large number of operators; in addition to the standard there were exoti
ones for operating on mays. However, when the language was eventually implemente
on a computer, several operators were omitted, but it still remained in its programmin
language form a remarkably 'rich' language.
APL has a large alphabet (52 letters, 10 digits and 52 other characters) and th
following unusual characteristics:
APL generally requires a programming technique very different from that used wit
traditional scientific languages. Indeed, many programmers find the ability to program
in a traditional language is more of a hindrance than a help when using APL. To b
successful, a programmer needs to envisage what effect different operators, either o
their ownor in conjunction withother operators, have onarrays. Programs oftencontain
therefore, a succession of such operators. The designer lverson recommended beginner
to 'play' with the language to get a feel for the effect of the operators, both on the
own and in conjunction.
Although there has been a lot of controversy about APL, it nevertheless seems t
attract devotees who consider it the only language for the programmer. It has also bee
suggested that it brings computing and mathematics closer together.
32 Historical survey
all the characters in the string and, when s is a strncture, generates all the elements in
the structure.
List-processing languages
In the early scientific languages (Fortran and Algol), the only data structure was the
array. All of its elements were of the same type and, in the case of Fortran, it was o
fixed size. Although COBOL had a data structure that allowed elements of differen
types, in none of these early languages was there scope for altering the basic structure
of the array. This is in essence what list~processingaccomplishes, usually by having an
element divided into an information part and a pointer part. The pointer part can, in th
case of a linked list, reference the next element in the list, but in tree structures there
are usually at least two pointers. In general, the linkage can he as complex as required
by the problem although in languages such as Lisp the pointers are implicit.
The early list-processing languages were developed to show the value of such pro
cessing in the programming environment. The first such language was IPL-V, which
was developed at the Camegie Institute of Technology in the period 1957-61. IPL-V
was really anassembly level set of commands for doing list processing on ahypothetica
machine - the commands were interpreted. The significance of IPL-V was to define th
concept of a list and to show how it could be implemented, albeit very crudely. It wa
used mainly by those programming artificial intelligence problems and it pioneered
many of the fundamental concepts of list processing - in particular, the idea of a fre
space list from which storage space for new elements of the list could be obtained an
to which storage space could be returned when no longer required.
The other early list-processing language, Lisp, has had a more lasting effect on
programming language design. It was developed by John McCarthy at MIT in the lat
1950s and he and his co-workers produced a workable language in the early 1960s.
The principal features of Lisp are as follows:
In addition to these features, Lisp was probably the first language to implemen
storage management by garbage collection. Lisp as implemented on a computer i
34 Historical survey
somewhat different from the 'pure' Lisp of the original definitions. It does, however,
come close to being a functional language (as pure Lisp is). A functional language
has as its fundamental operation the evaluation of expressions. This is in contrast to the
majority of languages (Fortran, Pascal, C++, Java), known as imperative languages,
which use a sequence of commands to carry out the desired operations. Interest in func-
tional languages increased significantly during the 1980s and their recent development
is discussed in Section 2.9.
Lisp has survived as a language despite the death of most list-processing languages
and there are several reasons for this. It is an elegant mathematical system, with a
simple basic functional structure capable of expressing the ideas of the Lambdacalculus.
These features, together with the fact that Lisp systems allow programs to he developed
interactively, make Lisp well suited to artificial intelligence applications. Finally, the
survival of Lisp has been helpedby the development of modem dialects such as Scheme,
and an agreement on a standard version of the language known as Common Lisp.
The early 1960s saw arash of List-processing languages: for example, L6, IE'L, SLIP,
WISP. However, their day was soon over as the general-purpose languages (Algol W,
Algol 68, PL/l and Pascal) started to include list processing within the language.
Simulation languages
The simulation of discrete systems was one of the first problems that computers were
used to solve. These systems are modelled by a series of state changes that often occur
in parallel. Complex interactions could arise between the elements of the system as
they compete for restricted system resources. The simulation technique itself follows
the system elements through their changes of state gathering quantitative information.
This information is then used to predict the properties of the system under hypothetical
situations. For example, simulation of a traffic system can predict bow the proposed
model will perform as traffic densities increase and hopefully show where bottlenecks
could occur.
The earliest simulation language to be widely used was GPSS (General-Purpose
Simulation System). Although it was first described in 1961, it was somewhat later
before the system was available to programmers. In GPSS, the system being simulated
is described by a blockdiagram in which the blocks represent the activities and the lines
joining the blocks indicate the logical sequence in which the activities can be executed.
When there is a choice of activities, this is represented by several lines leaving a block
and the conditions under which this choice is made is stated in the block.
GPSS has often been criticisedfor the slow execution time of its programs. While not
denying the slow run time, whichis due mainly to the use of interpretative programming
to implement the block diagram, the designers point out that the ease of using GPSS
means that the overall time for developing the model and obtaining the final results is
shorter than that in many other languages.
In Europe in the early 1960s a group led by Ole-Johan Dahl and Kristan Nygaard
at the Norwegian Computer Centre were also designing a simulation language which
eventually became known as Simula 67, although this was not the first working version
of the language. It was designed for system description and simulation; a system in this
case being a collection of independent objects with a common objective. Systems were
Special-purpose languages 3
Scripting languages
A common task in programming is the need either to analyse a large amount of textu
information or to convert it from one format to another. Central to such a task is th
ability to perform pattern matching on strings of characters. Often, such a task can b
programmed in only a few lines in a language with suitable pattern matching facilitie
while it takes considerable programming effort in a traditional language like C. Speci
pattern matching languages such as awk have been developed for this purpose. A mor
recent language is Perl which combines the power of awk with a more convention
syntax based on C.
Both Perl and awk were developed for the Unix operating system, but Perl is no
widely available on other platforms. Perl has grown into a large language with function
and modules and the ability to support object-oriented programming. A major use o
scripting languages like Perl is with the World Wide Web. Often, a Web client an
server need to communicate with each other and this is done through what is known a
the Common Gateway Interface (CGI). Perl is one of the most popular languages fo
writing CGI programs. Other scripting languages include Python, Tcl and JavaScript
Variables in Perl do not have a type, but are classified as scalar (numbers and strings
array or hash and have the prefix $, @ and 8 respectively. Hash variables are associativ
arrays and we can write:
To access the value of an element we write $month[ "May") which gives us the scal
value 31. Arrays can be extended and so we can add elements by writing for exampl
$month["July"]= 31;
I6 Historical survey
Note that we use the prefix $ as each element of %month is a scalar There are
extensive pattern matching facilities which use a notation that will be familiar to those
used to Unix editors and utilities. For example, if $st has the value " H i , there " ,
the statement:
will replace the string " i , " by "ello"and so $st will now have the value "Hello
there".The subsequent statement:
will transform each lower case character in the range a to m into its upper case
counterpart. Hence, $st will now have the value "HELLO tHErE".
Scripting languages are for getting things done quickly and simply. In many ways,
they are 'glue languages' used to facilitate communication between programs written
in other languages.
C
Historically, C evolved from BCPL through the language B during the years 1969-73
and was the systems programming language used to implement the Unix operating