62328
62328
62328
com
https://ebookfinal.com/download/programming-language-design-
concepts-1st-edition-david-a-watt/
OR CLICK BUTTON
DOWNLOAD EBOOK
https://ebookfinal.com/download/head-first-programming-a-learner-s-
guide-to-programming-using-the-python-language-1st-edition-david-
griffiths/
ebookfinal.com
https://ebookfinal.com/download/design-concepts-with-code-a-developer-
approach-1st-edition-kelly-carey/
ebookfinal.com
https://ebookfinal.com/download/concepts-of-programming-
languages-10th-edition-robert-w-sebesta/
ebookfinal.com
https://ebookfinal.com/download/concepts-of-programming-languages-7th-
edition-robert-w-sebesta/
ebookfinal.com
David Perry on Game Design A Brainstorming ToolBox 1st
Edition David Perry
https://ebookfinal.com/download/david-perry-on-game-design-a-
brainstorming-toolbox-1st-edition-david-perry/
ebookfinal.com
https://ebookfinal.com/download/denotational-semantics-a-methodology-
for-language-development-david-a-schmidt/
ebookfinal.com
https://ebookfinal.com/download/english-as-a-global-language-2nd-
edition-david-crystal/
ebookfinal.com
https://ebookfinal.com/download/beginning-regular-expressions-1st-
edition-andrew-watt/
ebookfinal.com
https://ebookfinal.com/download/sams-teach-yourself-javascript-
in-21-days-1st-edition-jonathan-a-watt/
ebookfinal.com
PROGRAMMING LANGUAGE
DESIGN CONCEPTS
All Rights Reserved. No part of this publication may be reproduced, stored in a retrieval system or transmitted in
any form or by any means, electronic, mechanical, photocopying, recording, scanning or otherwise, except under
the terms of the Copyright, Designs and Patents Act 1988 or under the terms of a licence issued by the Copyright
Licensing Agency Ltd, 90 Tottenham Court Road, London W1T 4LP, UK, without the permission in writing of the
Publisher, with the exception of any material supplied specifically for the purpose of being entered and executed
on a computer system for exclusive use by the purchase of the publication. Requests to the Publisher should be
addressed to the Permissions Department, John Wiley & Sons Ltd, The Atrium, Southern Gate, Chichester, West
Sussex PO19 8SQ, England, or emailed to permreq@wiley.co.uk, or faxed to (+44) 1243 770620.
This publication is designed to provide accurate and authoritative information in regard to the subject matter
covered. It is sold on the understanding that the Publisher is not engaged in rendering professional services. If
professional advice or other expert assistance is required, the services of a competent professional should be sought.
John Wiley & Sons Inc., 111 River Street, Hoboken, NJ 07030, USA
John Wiley & Sons Australia Ltd, 33 Park Road, Milton, Queensland 4064, Australia
John Wiley & Sons (Asia) Pte Ltd, 2 Clementi Loop #02-01, Jin Xing Distripark, Singapore 129809
John Wiley & Sons Canada Ltd, 22 Worcester Road, Etobicoke, Ontario, Canada M9W 1L1
Wiley also publishes its books in a variety of electronic formats. Some content that appears
in print may not be available in electronic books.
A catalogue record for this book is available from the British Library
ISBN 0-470-85320-4
Preface xv
Part I: Introduction 1
1 Programming languages 3
1.1 Programming linguistics 3
1.1.1 Concepts and paradigms 3
1.1.2 Syntax, semantics, and pragmatics 5
1.1.3 Language processors 6
1.2 Historical development 6
Summary 10
Further reading 10
Exercises 10
vii
viii Contents
10 Concurrency 231
10.1 Why concurrency? 231
10.2 Programs and processes 233
10.3 Problems with concurrency 234
10.3.1 Nondeterminism 234
10.3.2 Speed dependence 234
10.3.3 Deadlock 236
10.3.4 Starvation 237
10.4 Process interactions 238
10.4.1 Independent processes 238
10.4.2 Competing processes 238
10.4.3 Communicating processes 239
10.5 Concurrency primitives 240
10.5.1 Process creation and control 241
10.5.2 Interrupts 243
10.5.3 Spin locks and wait-free algorithms 243
10.5.4 Events 248
10.5.5 Semaphores 249
10.5.6 Messages 251
10.5.7 Remote procedure calls 252
10.6 Concurrent control abstractions 253
10.6.1 Conditional critical regions 253
10.6.2 Monitors 255
10.6.3 Rendezvous 256
Summary 258
Further reading 258
Exercises 259
Summary 328
Further reading 328
Exercises 329
The first programming language I ever learned was ALGOL60. This language was
notable for its elegance and its regularity; for all its imperfections, it stood head and
shoulders above its contemporaries. My interest in languages was awakened, and
I began to perceive the benefits of simplicity and consistency in language design.
Since then I have learned and programmed in about a dozen other languages,
and I have struck a nodding acquaintance with many more. Like many pro-
grammers, I have found that certain languages make programming distasteful, a
drudgery; others make programming enjoyable, even esthetically pleasing. A good
language, like a good mathematical notation, helps us to formulate and communi-
cate ideas clearly. My personal favorites have been PASCAL, ADA, ML, and JAVA.
Each of these languages has sharpened my understanding of what programming
is (or should be) all about. PASCAL taught me structured programming and data
types. ADA taught me data abstraction, exception handling, and large-scale pro-
gramming. ML taught me functional programming and parametric polymorphism.
JAVA taught me object-oriented programming and inclusion polymorphism. I had
previously met all of these concepts, and understood them in principle, but I did
not truly understand them until I had the opportunity to program in languages
that exposed them clearly.
Contents
This book consists of five parts.
Chapter 1 introduces the book with an overview of programming linguistics
(the study of programming languages) and a brief history of programming and
scripting languages.
Chapters 2–5 explain the basic concepts that underlie almost all programming
languages: values and types, variables and storage, bindings and scope, procedures
and parameters. The emphasis in these chapters is on identifying the basic
concepts and studying them individually. These basic concepts are found in almost
all languages.
Chapters 6–10 continue this theme by examining some more advanced con-
cepts: data abstraction (packages, abstract types, and classes), generic abstraction
(or templates), type systems (inclusion polymorphism, parametric polymor-
phism, overloading, and type conversions), sequencers (including exceptions), and
concurrency (primitives, conditional critical regions, monitors, and rendezvous).
These more advanced concepts are found in the more modern languages.
Chapters 11–16 survey the most important programming paradigms, compar-
ing and contrasting the long-established paradigm of imperative programming
with the increasingly important paradigms of object-oriented and concurrent pro-
gramming, the more specialized paradigms of functional and logic programming,
and the paradigm of scripting. These different paradigms are based on different
xv
xvi Preface
selections of key concepts, and give rise to sharply contrasting styles of language
and of programming. Each chapter identifies the key concepts of the subject
paradigm, and presents an overview of one or more major languages, showing
how concepts were selected and combined when the language was designed.
Several designs and implementations of a simple spellchecker are presented to
illustrate the pragmatics of programming in all of the major languages.
Chapters 17 and 18 conclude the book by looking at two issues: how to select
a suitable language for a software development project, and how to design a
new language.
The book need not be read sequentially. Chapters 1–5 should certainly be
read first, but the remaining chapters could be read in many different orders.
Chapters 11–15 are largely self-contained; my recommendation is to read at least
some of them after Chapters 1–5, in order to gain some insight into how major
languages have been designed. Figure P.1 summarizes the dependencies between
the chapters.
1
Introduction
2 3 4 5
Values and Variables and Bindings and Procedural
Types Storage Scope Abstraction
6 7 8 9 10
Data Generic Type Control Concurrency
Abstraction Abstraction Systems Flow
11 12 13 14 15 16
Imperative OO Concurrent Functional Logic Scripting
Programming Programming Programming Programming Programming
17 18
Language Language
Selection Design
Exercises
Each chapter is followed by a number of relevant exercises. These vary from
short exercises, through longer ones (marked *), up to truly demanding ones
(marked **) that could be treated as projects.
A typical exercise is to analyze some aspect of a favorite language, in the
same way that various languages are analyzed in the text. Exercises like this are
designed to deepen readers’ understanding of languages that they already know,
and to reinforce understanding of particular concepts by studying how they are
supported by different languages.
A typical project is to design some extension or modification to an existing
language. I should emphasize that language design should not be undertaken
lightly! These projects are aimed particularly at the most ambitious readers, but
all readers would benefit by at least thinking about the issues raised.
Readership
All programmers, not just language specialists, need a thorough understanding
of language concepts. This is because programming languages are our most
fundamental tools. They influence the very way we think about software design
and implementation, about algorithms and data structures.
This book is aimed at junior, senior, and graduate students of computer
science and information technology, all of whom need some understanding of
the fundamentals of programming languages. The book should also be of inter-
est to professional software engineers, especially project leaders responsible
for language evaluation and selection, designers and implementers of language
processors, and designers of new languages and of extensions to existing languages.
To derive maximum benefit from this book, the reader should be able to
program in at least two contrasting high-level languages. Language concepts can
best be understood by comparing how they are supported by different languages. A
reader who knows only a language like C, C++, or JAVA should learn a contrasting
language such as ADA (or vice versa) at the same time as studying this book.
The reader will also need to be comfortable with some elementary concepts
from discrete mathematics – sets, functions, relations, and predicate logic – as
these are used to explain a variety of language concepts. The relevant mathematical
concepts are briefly reviewed in Chapters 2 and 15, in order to keep this book
reasonably self-contained.
This book attempts to cover all the most important aspects of a large subject.
Where necessary, depth has been sacrificed for breadth. Thus the really serious
xviii Preface
student will need to follow up with more advanced studies. The book has an
extensive bibliography, and each chapter closes with suggestions for further
reading on the topics covered by the chapter.
Acknowledgments
Bob Tennent’s classic book Programming Language Principles has profoundly
influenced the way I have organized this book. Many books on programming
languages have tended to be syntax-oriented, examining several popular languages
feature by feature, without offering much insight into the underlying concepts
or how future languages might be designed. Some books are implementation-
oriented, attempting to explain concepts by showing how they are implemented
on computers. By contrast, Tennent’s book is semantics-oriented, first identifying
and explaining powerful and general semantic concepts, and only then analyzing
particular languages in terms of these concepts. In this book I have adopted Ten-
nent’s semantics-oriented approach, but placing far more emphasis on concepts
that have become more prominent in the intervening two decades.
I have also been strongly influenced, in many different ways, by the work
of Malcolm Atkinson, Peter Buneman, Luca Cardelli, Frank DeRemer, Edsger
Dijkstra, Tony Hoare, Jean Ichbiah, John Hughes, Mehdi Jazayeri, Bill Joy, Robin
Milner, Peter Mosses, Simon Peyton Jones, Phil Wadler, and Niklaus Wirth.
I wish to thank Bill Findlay for the two chapters (Chapters 10 and 13) he has
contributed to this book. His expertise on concurrent programming has made this
book broader in scope than I could have made it myself. His numerous suggestions
for my own chapters have been challenging and insightful.
Last but not least, I would like to thank the Wiley reviewers for their
constructive criticisms, and to acknowledge the assistance of the Wiley editorial
staff led by Gaynor Redvers-Mutton.
David A. Watt
Brisbane
March 2004
PART I
INTRODUCTION
1
Chapter 1
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
BASIC CONCEPTS
Part II explains the more elementary programming language concepts, which are
supported by almost all programming languages:
• values and types
• variables and storage
• bindings and scope
• procedural abstraction (procedures and parameters).
13
Chapter 2
Data are the raw material of computation, and are just as important (and valuable) as the
programs that manipulate the data. In computer science, therefore, the study of data is
considered as an important topic in its own right.
In this chapter we shall study:
• types of values that may be used as data in programming languages;
• primitive, composite, and recursive types;
• type systems, which group values into types and constrain the operations that may
be performed on these values;
• expressions, which are program constructs that compute new values;
• how values of primitive, composite, and recursive types are represented.
(In Chapter 3 we shall go on to study how values may be stored, and in Chapter 4 how
values may be bound to identifiers.)
2.1 Types
A value is any entity that can be manipulated by a program. Values can be
evaluated, stored, passed as arguments, returned as function results, and so on.
Different programming languages support different types of values:
• C supports integers, real numbers, structures, arrays, unions, pointers to
variables, and pointers to functions. (Integers, real numbers, and pointers
are primitive values; structures, arrays, and unions are composite values.)
• C++, which is a superset of C, supports all the above types of values plus
objects. (Objects are composite values.)
• JAVA supports booleans, integers, real numbers, arrays, and objects.
(Booleans, integers, and real numbers are primitive values; arrays and
objects are composite values.)
• ADA supports booleans, characters, enumerands, integers, real numbers,
records, arrays, discriminated records, objects (tagged records), strings,
pointers to data, and pointers to procedures. (Booleans, characters, enu-
merands, integers, real numbers, and pointers are primitive values; records,
arrays, discriminated records, objects, and strings are composite values.)
Most programming languages group values into types. For instance, nearly
all languages make a clear distinction between integer and real numbers. Most
15
16 Chapter 2 Values and types
languages also make a clear distinction between booleans and integers: integers
can be added and multiplied, while booleans can be subjected to operations like
not, and, and or.
What exactly is a type? The most obvious answer, perhaps, is that a type is a
set of values. When we say that v is a value of type T, we mean simply that v ∈ T.
When we say that an expression E is of type T, we are asserting that the result of
evaluating E will be a value of type T.
However, not every set of values is suitable to be regarded as a type. We insist
that each operation associated with the type behaves uniformly when applied to all
values of the type. Thus {false, true} is a type because the operations not, and, and or
operate uniformly over the values false and true. Also, {. . . , −2, −1, 0, +1, +2, . . .}
is a type because operations such as addition and multiplication operate uniformly
over all these values. But {13, true, Monday} is not a type, since there are no useful
operations over this set of values. Thus we see that a type is characterized not only
by its set of values, but also by the operations over that set of values.
Therefore we define a type to be a set of values, equipped with one or more
operations that can be applied uniformly to all these values.
Every programming language supports both primitive types, whose values are
primitive, and composite types, whose values are composed from simpler values.
Some languages also have recursive types, a recursive type being one whose
values are composed from other values of the same type. We examine primitive,
composite, and recursive types in the next three sections.
Character, Integer, and Float as names for the most common primitive types:
Boolean = {false, true} (2.1)
Character = {. . . , ‘a’, . . . , ‘z’, . . . , ‘0’, . . . , ‘9’, . . . , ‘?’, . . .} (2.2)
Integer = {. . . , −2, −1, 0, +1, +2, . . .} (2.3)
Float = {. . . , −1.0, . . . , 0.0, . . . , +1.0, . . .} (2.4)
(Here we are focusing on the set of values of each type.)
The Boolean type has exactly two values, false and true. In some languages
these two values are denoted by the literals false and true, in others by
predefined identifiers false and true.
The Character type is a language-defined or implementation-defined set of
characters. The chosen character set is usually ASCII (128 characters), ISO LATIN
(256 characters), or UNICODE (65 536 characters).
The Integer type is a language-defined or implementation-defined range of
whole numbers. The range is influenced by the computer’s word size and integer
arithmetic. For instance, on a 32-bit computer with two’s complement arithmetic,
Integer will be {−2 147 483 648, . . . , +2 147 483 647}.
The Float type is a language-defined or implementation-defined subset of the
(rational) real numbers. The range and precision are determined by the computer’s
word size and floating-point arithmetic.
The Character, Integer, and Float types are usually implementation-defined,
i.e., the set of values is chosen by the compiler. Sometimes, however, these
types are language-defined, i.e., the set of values is defined by the programming
language. In particular, JAVA defines all its types precisely.
The cardinality of a type T, written #T, is the number of distinct values in T.
For example:
#Boolean = 2 (2.5)
#Character = 256 (ISO LATIN character set) (2.6a)
#Character = 65 536 (UNICODE character set) (2.6b)
Although nearly all programming languages support the Boolean, Character,
Integer, and Float types in one way or another, there are many complications:
• Not all languages have a distinct type corresponding to Boolean. For
example, C++ has a type named bool, but its values are just small integers;
there is a convention that zero represents false and any other integer
represents true. This convention originated in C.
• Not all languages have a distinct type corresponding to Character. For
example, C, C++, and JAVA all have a type char, but its values are just
small integers; no distinction is made between a character and its internal
representation.
• Some languages provide not one but several integer types.
For example, JAVA provides byte {−128, . . . , +127}, short
{−32 768, . . . , +32 767}, int {−2 147 483 648, . . . , +2 147 483 647}, and
long {−9 223 372 036 854 775 808, . . . , +9 223 372 036 854 775 807}. C and
18 Chapter 2 Values and types
C++ also provide a variety of integer types, but they are implementation-
defined.
• Some languages provide not one but several floating-point types. For
example, C, C++, and JAVA provide both float and double, of which the
latter provides greater range and precision.
The variable countryPop could be used to contain the current population of any country
(since no country yet has a population exceeding 2 billion). The variable worldPop could
be used to contain the world’s total population. But note that the program would fail if
worldPop’s type were int rather than long (since the world’s total population now
exceeds 6 billion).
A C++ program with the same declarations would be unportable: a C++ compiler may
choose {−65 536, . . . , +65 535} as the set of int values!
countryPop: Population;
worldPop: Population;
The integer type defined here has the following set of values:
Population = {0, . . . , 1010 }
2.2 Primitive types 19
defines Month to be an integer type, and binds jan to 0, feb to 1, and so on. Thus:
Month = {0, 1, 2, . . . , 11}
The indices of the array freq are values of type Character. Likewise, the loop control
variable ch takes a sequence of values of type Character.
Also consider the following ADA code:
The indices of the array length are values of type Month. Likewise, the loop control
variable mth takes a sequence of values of type Month.
Most programming languages allow only integers to be used for counting and
array indexing. C and C++ allow enumerands also to be used for counting and
array indexing, since they classify enumeration types as integer types.
that is concise, standard, and suitable for defining sets of values structured as
Cartesian products, mappings, and disjoint unions.
Here someday.m selects the first component, and someday.d the second component,
of the record someday. Note that the use of component identifiers m and d in record
construction and selection enables us to write code that does not depend on the order of
the components.
A special case of a Cartesian product is one where all tuple components are
chosen from the same set. The tuples in this case are said to be homogeneous.
For example:
S2 = S × S (2.9)
means the set of homogeneous pairs whose components are both chosen from set
S. More generally we write:
Sn = S × . . . × S (2.10)
to mean the set of homogeneous n-tuples whose components are all chosen from
set S.
The cardinality of a set of homogeneous n-tuples is given by:
#(Sn ) = (#S)n (2.11)
This motivates the superscript notation.
Finally, let us consider the special case where n = 0. Equation (2.11) tells us
that S0 should have exactly one value. This value is the empty tuple (), which is
the unique tuple with no components at all. We shall find it useful to define a type
that has the empty tuple as its only value:
Unit = {()} (2.12)
This type’s cardinality is:
#Unit = 1 (2.13)
Note that Unit is not the empty set (whose cardinality is 0).
Unit corresponds to the type named void in C, C++, and JAVA, and to the
type null record in ADA.
u v u v
S S
T T
a b c a b c
Figure 2.2 Two different mappings in
{u → a, v → c} {u → c, v → c} S → T.
{u → a, v → a} {u → a, v → b} {u → a, v → c}
→ =
u v a b c {u → b, v → a} {u → b, v → b} {u → b, v → c}
S T {u → c, v → a} {u → c, v → b} {u → c, v → c}
S→T
The indices of this array range from the lower bound 0 to the upper bound 2. The set of
possible values of this array is therefore:
{0, 1, 2} → {false, true}
The cardinality of this set of values is 23 , and the values are the following eight
finite mappings:
{0 → false, 1 → false, 2 → false} {0 → true, 1 → false, 2 → false}
{0 → false, 1 → false, 2 → true} {0 → true, 1 → false, 2 → true}
{0 → false, 1 → true, 2 → false} {0 → true, 1 → true, 2 → false}
{0 → false, 1 → true, 2 → true} {0 → true, 1 → true, 2 → true}
The following code illustrates array construction:
bool p[] = {true, false, true};
The following code illustrates array indexing (using an int variable c):
p[c] = !p[c];
or more concisely:
p: Pixel := (true, false, true);
The following code illustrates array indexing (using a Color variable c):
p(c) := not p(c);
while (m > 1) m -= 2;
return (m == 0);
}
implements a particular mapping in Float × Integer → Float. Presumably, it maps the pair
(1.5, 2) to 2.25, the pair (4.0, −2) to 0.0625, and so on.
left u left v
+ =
u v a b c
right a right b right c
S T Figure 2.4 Disjoint union of sets
S + T (or left S + right T ) S and T.
2.3 Composite types 29
This uses pattern matching. If the value of num is Inexact 3.1416, the pattern ‘‘Inexact
r’’ matches it, r is bound to 3.1416, and the subexpression ‘‘round r’’ is evaluated,
yielding 3.
From the time of the Ottoman conquest spiritual liberty has been
allowed to all creeds in Turkey, and the external observances and
ceremonies of religion have, in most places, been permitted by the
Moslems, though in some even funeral ceremonies were often
molested, and the use of church bells was forbidden. Certain rights
and privileges were granted to each church, to which the Christians
clung with great tenacity—as to a sacred banner, round which they
would one day rally and march to freedom.
By the concessions granted to the vanquished by their conquerors,
they were allowed to retain those churches that had escaped
destruction or were not converted into mosques, and permitted to
worship according to the dictates of their own consciences so long
as the sound of their bell calling the infidels to prayer did not offend
the ear of the faithful. The internal administration was not interfered
with; each congregation was free to choose its own clergy, ornament
the interior of its church as it saw fit, perform its pilgrimages and
bury its dead, without interference from the authorities. These
privileges, though looked upon as sacred by the poor, could not
compensate in the sight of the rich and once powerful for social and
material losses; thus many Christians renounced their faith and
adopted that of their masters.
Time and succeeding events have softened down some of the
outstanding wrongs; fanatical outbreaks and religious persecutions
have become of less frequent occurrence; and the various Hattis
proclaiming freedom of worship and religious equality to all Ottoman
subjects before the law, are guarantees that no arbitrary action on
the part of the government can interfere with the religious privileges
of the Christians, or deprive them of their rights. Though this
guarantee is a proof of the sincerity of the Porte in its efforts to give
satisfaction to its Christian subjects, it cannot remove the evil or
lessen its consequences, which remain in all their force of danger
and uncertainty. Every movement of discontent in Turkey receives a
strong impulse from that religious zeal which stimulates the
Mohammedan to acts of fanatical barbarity, and the Christian to a
superstitious belief in miraculous powers that will protect him in the
hour of danger. Thus, in times of disturbance the timorous bulk of
the population of a town or village will rush to the church for safety,
there pouring out mingled prayers and tears to God and all the
saints that the threatened danger may be averted. Rarely, it would
seem, are such prayers heard, for the first place to which the excited
Mussulman rushes is the church, and thither the brigand chief will
lead his band, and perpetrate acts of the most revolting barbarity.
The armed peasant, the undisciplined soldier, or the cruel and
licentious Bashi-Bazouk will all attack the sacred edifice, break it
open, and destroy or pollute all that falls into their hands. These are
the ever-recurring evils that no Imperial law will be able to prevent,
no measures eradicate, so long as the two rival creeds continue to
exist face to face, and be used as the principal motives in the
struggle, past and present, for supremacy on one side, freedom and
independence on the other. The Mussulmans, under pressure, will
grant every concession demanded of them, and to a great extent
carry them out; but it would be utterly erroneous to suppose for a
moment that under any pressure or in any degree of civilization, the
Turk would be able to disabuse himself of the deeply-rooted disdain
the most liberal-minded of his race feels for strangers to his creed
and nation.
The experiences of all thoroughly acquainted with the character of
the Ottoman tallies with mine on this point. I have seen the disdain
felt by the Mohammedan towards the Christian portrayed on the
faces of the most liberal, virtuous, and well-disposed, as well as on
those of the most bigoted. A Christian, be he European or Asiatic, is
an infidel in the Moslem’s sight. He will receive him graciously,
converse with him in the most amicable manner, and at the same
time mumble prayers for pardon for his sin in holding communication
with an unbeliever.
The religious freedom enjoyed by the members of the Protestant
and Roman Catholic churches is far more extensive than that
enjoyed by the Eastern. Both, upheld by the powerful support of
European powers, enjoy a liberty of action and license of speech
rarely found in other countries. Both are aliens and owe their origin
to the proselytizing efforts of the missionaries. The Church of Rome,
being the older and more enterprising, naturally commands a much
vaster field than the Protestant; she is supported by France and
other Roman Catholic countries, who jealously watch over her rights
and privileges. The Protestants are protected by England and
America; their missionaries entered Turkey at a later date and
gradually established themselves over the country. At first the
extremely reserved attitude of the missionaries, their conscientious
method of making converts, and the extreme severity of their
regulations, gave them but a poor chance of success. Gradually,
however, the esteem and regard of the people for them increased;
stringent opposition, promoted by sectarian dissensions, died out,
and mission stations, with numerous churches, some of considerable
importance and promise, were established, especially in Armenia.
The principal cause of the encouragement they met with was the
wise policy, lately adopted, of promoting missionary work by
education.
The extensive body of Protestant missionaries now found in
Turkey is almost entirely American. The meetings of the Board are
held in Constantinople; it controls the administration of the different
missions and directs the large American College at Bebek—the best
foreign institute for education in the country.
When a community of Protestant converts numbers a few families
it is given a church and school, and one of the principal men is
elected as chief of the society. This person is presented officially to
the authorities by one of the consuls of the protecting powers—
generally the English; he is recognized as chief of his community,
obtains a seat in the local court, and is intrusted with all the
interests of his co-religionists. In difficult or complicated cases the
missionaries themselves share the responsibilities of this chief, and
through consular or ambassadorial agency generally settle all
matters calling for redress and justice in a satisfactory manner.
The few English missionaries who are established in Turkey are
intrusted with the fruitless task of endeavoring to convert the Jews.
The Roman Catholic missionaries, from the date of the separation
of the Eastern and Western Churches, have ever been actively and
diligently employed in making converts. Thus a great portion of the
population of Syria, yielding to their influence, has become Roman
Catholic, as have the Bosnians, a portion of the Albanians, some of
the Greeks inhabiting the islands, the Armenians of Constantinople,
and of later years a small portion of the Bulgarians. The action of
the missionaries of late years has not, however, been so much
directed towards making new converts as it has to consolidating and
strengthening the tie binding the few scattered communities to the
mother-church. This religious body recruits itself chiefly from France
and Italy, and consists of priests, monks, and Sisters of Charity,
belonging chiefly to the orders of St. Benois, the Jesuits, Lazarists,
and St. Vincent de Paul. Their extensive establishments are situated
in the Frank quarters of the towns, and consist of well-built and
spacious churches, monasteries, schools, orphan asylums, and
foundling hospitals. Pera and Galata contain a goodly number of
these establishments, as do the principal towns of European and
Asiatic Turkey. These missions are evidently well furnished with
funds, for their establishments have everywhere a prosperous
appearance, and are provided with every requisite for the purposes
for which they are intended. The religious instruction given in them
is, however, extremely illiberal, bigoted, and imparted on Jesuitical
principles. Exclusiveness and intolerance towards other creeds are
openly prescribed. “Point de salut hors de l’Eglise” is their doctrine.
Considerable laxity is allowed in moral points so long as they do not
interfere with the external duties of the community to the church.
Should an individual belonging to another creed die among the
community, the rite of burial will be refused to him by the Roman
Catholic priests, but those of the Orthodox Church will often in that
case consent to perform it. Even the marriage ceremony, unless
performed in their churches, is considered by the more bigoted
portion of the Roman Catholic clergy as not binding. This strange
statement was made in my presence before a large gathering of
persons belonging to different creeds, by the superior of a Lazarist
establishment at A⸺. It was on the occasion of the marriage of
two members of the Latin community of that town, when the service
was terminated by the following short address to the married
couple: “Twice happy are you to belong to the Holy Church of Rome
and to be united in the sacred ties of matrimony within her bosom:
for in the same manner as there is no hope after life for those who
do not belong to her, so marriage is not binding out of her, but every
woman who so gives herself is not a legal wife but a concubine!” In
many cases the sacrament is refused to ladies united in marriage to
persons belonging to other creeds.
The secular teaching given in the schools of these missions is
limited, and, based on the same principles as the religion, is illiberal
and narrow-minded. Much time is consecrated by the pupils to
religious recitations, prayers, and penances of no possible profit to
the children. Thus from an early age, imbued with narrow ideas and
made to lose sight of the spirit of Christianity, the Roman Catholic
communities, be they of European, Greek, or Armenian nationality,
are the most bigoted, intolerant, and exclusive of all the Christian
communities of the East.
The missionaries belonging to this Church are unsurpassed in the
admirable manner in which their charitable establishments are
arranged. The homes and asylums for the poor and orphan children
are for the girls under the control of the Sisters of Charity, and for
the boys under that of the priests and monks. These are well kept,
and very orderly, the food is good and abundant, and the dress of
the children solid and befitting their condition. Hospitals are attached
to each establishment, where the sick are well cared for and
destitute Europeans admitted irrespective of creed. The good Sisters
of Charity take upon themselves the duty of watching over the
patients night and day. A dispensary is included in each mission
station, where medicines and medical advice are given gratuitously.
The children reared in these establishments are placed in situations
on leaving them; but I regret to be obliged to say that comparatively
few of either sex are known to turn out honest and respectable.
The retired lives led by these active servants of Rome do not
prevent their being very intimately connected with their respective
communities or using their all-powerful influence for good or for evil
in all family concerns. They are hardy, active, and most persevering;
their personal wants are small and their mode of living modest and
unassuming. But in spite of this they are worldly-wise, crafty, and
unscrupulous as to the means they use in obtaining their ends. Their
mode of action is based upon the principle that the end justifies the
means; few, therefore, are the scruples that will arrest their action
or the dangers and difficulties that will damp their courage or check
their ardor in their work.
All the internal regulations and arrangements of the Catholic
community are made without the Porte troubling itself much about
them—indeed, to do the Turk justice, in his high contempt for things
Christian, he keeps as much as possible out of the religious
dissensions of his subjects, and when by chance he does appear on
the scene of action, by turns persecutor, protector, or peacemaker,
he is generally prompted in the matter by one of the interested
parties. An amusing incident witnessed by one of my friends at
Jerusalem well illustrates this fact. This gentleman accompanied one