(Download pdf) Programming Languages Principles And Paradigms 2Nd Edition Maurizio Gabbrielli ebook online full chapter

You might also like

Download as pdf or txt
Download as pdf or txt
You are on page 1of 53

Programming Languages: Principles

and Paradigms (2nd Edition) Maurizio


Gabbrielli
Visit to download the full and correct content document:
https://ebookmeta.com/product/programming-languages-principles-and-paradigms-2n
d-edition-maurizio-gabbrielli/
More products digital (pdf, epub, mobi) instant
download maybe you interests ...

Programming Languages and Systems Ilya Sergey

https://ebookmeta.com/product/programming-languages-and-systems-
ilya-sergey/

Programming Languages Application and Interpretation


printing Shriram Krishnamurthi

https://ebookmeta.com/product/programming-languages-application-
and-interpretation-printing-shriram-krishnamurthi/

Programming Languages Build Prove and Compare Norman


Ramsey

https://ebookmeta.com/product/programming-languages-build-prove-
and-compare-norman-ramsey/

Emerging Computing Paradigms Principles Advances and


Applications 1st Edition San Murugesan

https://ebookmeta.com/product/emerging-computing-paradigms-
principles-advances-and-applications-1st-edition-san-murugesan/
Primary Mathematics 3A Hoerst

https://ebookmeta.com/product/primary-mathematics-3a-hoerst/

Internet of Things IoT Principles Paradigms and


Applications of IoT English Edition Lakhwani

https://ebookmeta.com/product/internet-of-things-iot-principles-
paradigms-and-applications-of-iot-english-edition-lakhwani/

Concepts of Programming Languages 12th Edition Robert


W. Sebesta

https://ebookmeta.com/product/concepts-of-programming-
languages-12th-edition-robert-w-sebesta/

Seven Languages in Seven Weeks A Pragmatic Guide to


Learning Programming Languages Bruce A. Tate

https://ebookmeta.com/product/seven-languages-in-seven-weeks-a-
pragmatic-guide-to-learning-programming-languages-bruce-a-tate/

Foundations of Probabilistic Logic Programming.


Languages, Semantics, Inference and Learning 2nd
Edition Fabrizio Riguzzi

https://ebookmeta.com/product/foundations-of-probabilistic-logic-
programming-languages-semantics-inference-and-learning-2nd-
edition-fabrizio-riguzzi/
Undergraduate Topics in Computer Science

Maurizio Gabbrielli
Simone Martini

Programming
Languages:
Principles
and Paradigms
Second Edition
Undergraduate Topics in Computer
Science

Series Editor
Ian Mackie, University of Sussex, Brighton, UK

Advisory Editors
Samson Abramsky , Department of Computer Science, University of Oxford,
Oxford, UK
Chris Hankin , Department of Computing, Imperial College London, London, UK
Mike Hinchey , Lero – The Irish Software Research Centre, University of
Limerick, Limerick, Ireland
Dexter C. Kozen, Department of Computer Science, Cornell University, Ithaca,
NY, USA
Andrew Pitts , Department of Computer Science and Technology, University of
Cambridge, Cambridge, UK
Hanne Riis Nielson , Department of Applied Mathematics and Computer Science,
Technical University of Denmark, Kongens Lyngby, Denmark
Steven S. Skiena, Department of Computer Science, Stony Brook University, Stony
Brook, NY, USA
Iain Stewart , Department of Computer Science, Durham University, Durham,
UK
Joseph Migga Kizza, College of Engineering and Computer Science, The University
of Tennessee-Chattanooga, Chattanooga, TN, USA
‘Undergraduate Topics in Computer Science’ (UTiCS) delivers high-quality
instructional content for undergraduates studying in all areas of computing and
information science. From core foundational and theoretical material to final-year
topics and applications, UTiCS books take a fresh, concise, and modern approach
and are ideal for self-study or for a one- or two-semester course. The texts are all
authored by established experts in their fields, reviewed by an international advisory
board, and contain numerous examples and problems, many of which include fully
worked solutions.
The UTiCS concept relies on high-quality, concise books in softback format,
and generally a maximum of 275–300 pages. For undergraduate textbooks that are
likely to be longer, more expository, Springer continues to offer the highly regarded
Texts in Computer Science series, to which we refer potential authors.
Maurizio Gabbrielli · Simone Martini

Programming Languages:
Principles and Paradigms
Second Edition

With a chapter by Saverio Giallorenzo


Maurizio Gabbrielli Simone Martini
Department of Computer Science Department of Computer Science
and Engineering and Engineering
University of Bologna University of Bologna
Bologna, Italy Bologna, Italy

ISSN 1863-7310 ISSN 2197-1781 (electronic)


Undergraduate Topics in Computer Science
ISBN 978-3-031-34143-4 ISBN 978-3-031-34144-1 (eBook)
https://doi.org/10.1007/978-3-031-34144-1

1st edition: © Springer-Verlag London Ltd., part of Springer Nature 2010


2nd edition: © The Editor(s) (if applicable) and The Author(s), under exclusive license to Springer
Nature Switzerland AG 2023

This work is subject to copyright. All rights are solely and exclusively licensed by the Publisher, whether
the whole or part of the material is concerned, specifically the rights of reprinting, reuse of illustrations,
recitation, broadcasting, reproduction on microfilms or in any other physical way, and transmission or
information storage and retrieval, electronic adaptation, computer software, or by similar or dissimilar
methodology now known or hereafter developed.
The use of general descriptive names, registered names, trademarks, service marks, etc. in this publication
does not imply, even in the absence of a specific statement, that such names are exempt from the relevant
protective laws and regulations and therefore free for general use.
The publisher, the authors, and the editors are safe to assume that the advice and information in this book
are believed to be true and accurate at the date of publication. Neither the publisher nor the authors or
the editors give a warranty, expressed or implied, with respect to the material contained herein or for any
errors or omissions that may have been made. The publisher remains neutral with regard to jurisdictional
claims in published maps and institutional affiliations.

This Springer imprint is published by the registered company Springer Nature Switzerland AG
The registered company address is: Gewerbestrasse 11, 6330 Cham, Switzerland
To Francesca and Antonella,
who will never want to read this book
but who contributed to it being written.
To Costanza, Maria and Teresa, who will
read it perhaps,
but who have done everything to stop it being
written.

In the end not only Francesca and Antonella


never read the book,
but also Costanza, Maria, and Teresa never
got to do it.
This second edition is dedicated also to
Daniela,
hoping that at least she will read it.
Foreword to the First Edition

With great pleasure, I accepted the invitation extended to me to write these few
lines of Foreword. I accepted for at least two reasons. The first is that the request
came to me from two colleagues for whom I have always had the greatest regard,
starting from the time when I first knew and appreciated them as students and as
young researchers.
The second reason is that the text by Gabbrielli and Martini is very near to the
book that I would have liked to have written but, for various reasons, never have.
In particular, the approach adopted in this book is the one which I myself have
followed when organizing the various courses on programming languages I have
taught for almost 30 years at different levels under various titles.
The approach, summarized in two words, is that of introducing the general
concepts (either using linguistic mechanisms or the implementation structures cor-
responding to them) in a manner that is independent of any specific language;
once this is done, “real languages” are introduced. This is the only approach that
allows one to reveal similarities between apparently quite different languages (and
also between paradigms). At the same time, it makes the task of learning different
languages easier. In my experience as a lecturer, ex-students recall the principles
learned in the course even after many years; they still appreciate the approach
which allowed them to adapt to technological developments without too much
difficulty.
The book by Gabbrielli and Martini has, as central reference point, an under-
graduate course in Computer Science. For this reason, it does not have complex
prerequisites and tackles the subject by finding a perfect balance between rigor
and simplicity. Particularly appreciated and successful is the force with which
they illuminate the connections with other important “areas of theory” (such
as formal languages, computability, semantics) which the book rightly includes
(a further justification for their inclusion being that these topics are no longer
taught in many degree courses).

Pisa, Italy Giorgio Levi


Fall 2005

vii
Preface to the Second Edition

For this second English edition, we have extensively revised the translation of the
first printing. As well as correcting errata, we have updated the existing mate-
rial, clarified some tricky points, and discussed newer programming languages,
with Python as the main reference. Almost every page of the previous edition has
changed in some way.
We also added three final chapters, on topics that we felt are too important
today to be omitted, even in an undergraduate level textbook.
The first regards constraint programming. It represents the third approach seen
in this book to declarative programming, which has a wide range of applications in
artificial intelligence. We discuss the main ideas behind the paradigm and we illus-
trate the two main ways to implement it: constraint logic programs and constraint
programming in the context of an imperative language. For the latter approach,
we use MinZinc as a reference language. Following the guiding principle of the
book, we do not want to teach constraint logic programming, MinZinc or any other
specific language, but we rather provide enough background for appreciating the
potential that constraint programming has in many application areas.
The second new chapter concerns concurrent programming. Although our aim
remains that of an introductory textbook, the absence of any reference to concur-
rency seemed to us too conspicuous a gap, given that a significant part of software
today exploits concurrency, from the operating system level up to the Web ser-
vices. An exhaustive treatment of this topic would require (at least) a volume by
itself. The chapter illustrates only the main problems that arise when switching
from sequential to concurrent programs, together with the relative solutions. We
tried to offer an adequate panorama of the main techniques and linguistic con-
structs for realizing interaction mechanisms, synchronization, and communication
between concurrent programs or processes. Following the guiding principle of the
whole book, we have not referred to a specific language, even if we have tried to
make some notions concrete by examining the case of Java.
The third new chapter, written by Saverio Giallorenzo, in a way, rounds up the
tour we started in the chapter on concurrency. We focus on a specific form of the
concurrent paradigm, distributed programming, and we introduce service orienta-
tion. Distribution (as in “processes not sharing memory”) presents both challenges
and opportunities. We highlight how dedicated programming language constructs

ix
x Preface to the Second Edition

have evolved to tackle these issues and seize their strengths to support the devel-
opment of open-ended, complex distributed programs through principles such as
loose coupling and interoperability. We also explore the fundamental concepts of
services, their traits, the related language constructs, and the challenges and sup-
port for verifying the correctness of service-oriented programs. As done in the
previous chapters, we never focus on a specific language, and we maintain an
open perspective. We explore how languages from this landscape implemented the
same concepts, introduced different solutions to common issues, or rather evolved
following different interpretations of the same ideas. In the chapter, we also pro-
vide an overview of the role of service-oriented architectures and cloud computing
in the development and evolution of the service-oriented paradigm.

Use of the Book

The book is primarily a university textbook, but it is also suitable for the personal
education of IT specialists who want to deepen their knowledge of the mechanisms
behind the languages they use. The choice of themes and the presentation style
are largely influenced by the experience of teaching the content as part of the
bachelor’s degree in Computer Science of the School of Sciences at Alma Mater
Studiorum—Università di Bologna.
In our experience, the book can cover two modules of six credits, placed in the
second or third year of the bachelor’s degree. A first module can cover abstract
machines and the fundamental aspects, say Chaps. 1–9. The other can cover (some
of) the different paradigms. As the maturity of students increases it also increases
the amount of material one can present.

Acknowledgements

M. G. and S. M. are happily indebted to Saverio Giallorenzo for his prodding to


finish this second edition. Besides writing Chap. 15 on service-oriented program-
ming, he reviewed the chapter on concurrency, revised and extended the one on
history, and made many more valuable contributions to the text of the whole book.
We would like to thank the people who have kindly helped us with the new
chapters included in the second edition. Roberto Amadini read a draft of the
chapter on constraint programming and provided useful insights and comments.
Fabrizio Montesi and Florian Rademacher read drafts of the chapter on service
orientation and helped to improve it with their generous feedback, insights, and
errata.

Bologna, Italy Maurizio Gabbrielli


Spring 2023 Simone Martini
Saverio Giallorenzo
Preface to the First Edition

Facilius per partes in cognitionem totius adducimur


(Seneca, Epist. 89, 1)

Learning a programming language, for most students in computing, is akin to a rite


of passage. It is an important transition, soon recognized as insufficient. Among
the tools of the trade, there are many languages, so an important skill for a good
IT specialist is to know how to move from one language to another (and how to
learn new ones) with naturalness and speed.
This competence is not obtained by learning many different languages from
scratch. Programming languages, like natural languages, have their similarities,
analogies, cross-pollination phenomena, and genealogies that influence their char-
acteristics. If it is impossible to learn tens of languages well, it is possible to
deeply understand the mechanisms that inspire and guide the design and imple-
mentation of hundreds of different languages. This knowledge of the “parts” eases
the understanding of the “whole” of a new language and, therefore, underpins a
fundamental methodological competence in the professional life of IT specialists,
at least as far as it allows them to anticipate innovations and outlive technologies
that grow obsolete.
It is for these reasons that a course on the general aspects of programming
languages is, throughout the world, a key step in the advanced education (univer-
sity or professional) of IT specialists. The fundamental competences which an IT
specialist must possess about programming languages are of at least four types:

• the proper linguistic aspects;


• how one can implement language constructs and what are the costs relative to
a given implementation;
• the architectural aspects that influence implementation;
• translation techniques (compilation).

A single course rarely deals with all four of these aspects. In particular, description
of the architectural aspects and compilation techniques are both topics that are
sufficiently complex and elaborate to deserve independent courses. The remaining
xi
xii Preface to the First Edition

aspects are primarily the content of a general course on programming languages


and comprise the main subject of this book.
The literature is rich in texts dealing with these subjects and generations of
students have used them in their education. All these texts, though, have in mind
an advanced reader who already understands many programming languages, who
has a more-than-superficial competence with the fundamental basic mechanisms,
and who is not afraid when confronted with a fragment of code written in an
unknown language (because they can understand it by looking at the analogies and
differences with those they already know). We can see these textbooks as focused
on the comparison among languages. These are long, deep, and stimulating books,
but they are too long and deep (read: difficult) for the student who begins their
career with a single programming language (or at most two) and who still has to
learn the basic concepts in detail.
This book aims to fill this gap. Experts will see that the index of topics pursues
in large measure classical themes. However, we treat these themes in an elementary
fashion, trying to assume as prerequisites only the bare minimum. We also strive
to not make the book a catalogue of the traits and differences of the existing pro-
gramming languages. The ideal (or reference) reader knows one language (well)
(for example, Pascal, C, C++, or Java); even better if they have had some exposure
to another language or paradigm. We avoided references to languages that are now
obsolete, and we rarely show code examples written in a specific programming
language. Mainly, the text freely uses a sort of pseudo-language (whose concrete
syntax was inspired by C and Java) and seeks, in this way, to describe the most
relevant aspects of different languages.
Every so often, a “box” at the top of the page presents an in-depth discus-
sion, a reminder of a basic concept or specific details about popular languages (C,
C++, Java; ML, and Lisp for functional languages; Prolog for logic programming
languages). The reader at the first reading can safely skip the material in boxes.
Every chapter contains a short sequence of exercises, intended as a way of
testing the understanding of the material. There are no truly difficult exercises or
requiring more than 10 min for their solution.
Chapter 3 (Foundations) deals with themes that are not usually present in a book
on programming languages. It is natural, however, while discussing static seman-
tics and comparing languages, to ask what are the limits of the static analysis
of programs and whether one can apply the same techniques to different lan-
guages. Rather than pointing the reader to other textbooks, given the conceptual
and pragmatic relevance of these questions, we decided to answer them directly.
In the space of a few pages, we present, in an informal but rigorous manner,
the undecidability of the halting problem and that all general-purpose program-
ming languages express the same class of computable functions. This allows us
to present to the student, who does not always have a complete course on the
“fundamentals” in their curriculum, the main results related to the limitations of
computational models, which we deem fundamental for their education.
Besides the principles, this book also introduces the main programming
paradigms: object-oriented, functional and logic. The need to write an introductory
Preface to the First Edition xiii

book and keep it within a reasonable length explains the exclusion of important
topics, such as concurrency and scripting languages for example.

Acknowledgements

Our thanks to Giorgio Levi go beyond the fact that he had the grace to write the
Foreword. Both of us owe to him our first understanding of the mechanisms that
underpin programming languages. His teaching appears in this book in a way that
is anything but marginal.
We have to thank the many people who kindly helped us in the realization
of the book. Ugo Dal Lago drew the figures using METAPOST and Cinzia Di
Giusto, Wilmer Ricciotti, Francesco Spegni, and Paolo Tacchella read and com-
mented on the drafts of some chapters. The following people pointed out misprints
and errors: Irene Borra, Ferdinanda Camporesi, Marco Comini, Michele Filannino,
Matteo Friscini, Stefano Gardenghi, Guido Guizzunti, Giacomo Magisano, Flavio
Marchi, Fabrizio Massei, Jacopo Mauro, Maurizio Molle, Mirko Orlandelli, Marco
Pedicini, Andrea Rappini, Andrea Regoli, Fabiano Ridolfi, Giovanni Rosignoli,
Giampiero Travaglini, and Fabrizio Giuseppe Ventola.
We gladly acknowledge the support of the Department of Computer Science
of Università di Bologna towards the English translation of the first edition of the
book.

Bologna, Italy Maurizio Gabbrielli


Fall 2005 Simone Martini
Contents

1 Abstract Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1
1.1 The Concepts of Abstract Machine and the Interpreter . . . . . . . . 1
1.1.1 The Interpreter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2
1.1.2 An Example of an Abstract Machine: The
Hardware Machine . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5
1.2 Implementation of a Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9
1.2.1 Implementation of an Abstract Machine . . . . . . . . . . . . . 9
1.2.2 Implementation: The Ideal Case . . . . . . . . . . . . . . . . . . . . . 11
1.2.3 Implementation: The Real Case
and the Intermediate Machine . . . . . . . . . . . . . . . . . . . . . . . 16
1.3 Hierarchies of Abstract Machines . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20
1.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22
1.5 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
1.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24
2 Describing a Programming Language . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.1 Levels of Description . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25
2.2 Grammar and Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27
2.2.1 Context-Free Grammars . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28
2.3 Contextual Syntactic Constraints . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 37
2.4 Compilers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39
2.5 Semantics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43
2.6 Pragmatics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
2.7 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
2.8 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 50
2.9 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
2.10 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 51
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 52
3 Foundations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.1 The Halting Problem . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 53
3.2 Undecidable Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 55
3.2.1 The Standard Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 56
3.2.2 More Undecidable Problems . . . . . . . . . . . . . . . . . . . . . . . . . 57
xv
xvi Contents

3.3 Formalisms for Computability . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 57


3.4 There Are More Functions Than Algorithms . . . . . . . . . . . . . . . . . 59
3.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60
3.6 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
3.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62
4 Names and the Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.1 Names and Denotable Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 63
4.1.1 Denotable Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 65
4.2 Environments and Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 66
4.2.1 Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 67
4.2.2 Types of Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 68
4.2.3 Operations on Environments . . . . . . . . . . . . . . . . . . . . . . . . . 71
4.3 Scope Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 73
4.3.1 Static Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 74
4.3.2 Dynamic Scope . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 76
4.3.3 Some Scope Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 78
4.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 80
4.5 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
4.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85
5 Memory Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 87
5.1 Techniques for Memory Management . . . . . . . . . . . . . . . . . . . . . . . . 87
5.2 Static Memory Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 89
5.3 Dynamic Memory Management Using Stacks . . . . . . . . . . . . . . . . 90
5.3.1 Activation Records for In-Line Blocks . . . . . . . . . . . . . . . 92
5.3.2 Activation Records for Procedures . . . . . . . . . . . . . . . . . . . 93
5.3.3 Stack Management . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 96
5.4 Dynamic Management Using a Heap . . . . . . . . . . . . . . . . . . . . . . . . . 97
5.4.1 Fixed-Length Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98
5.4.2 Variable-Length Blocks . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99
5.5 Implementation of Scope Rules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 102
5.5.1 Static Scope: The Static Chain . . . . . . . . . . . . . . . . . . . . . . . 102
5.5.2 Static Scope: The Display . . . . . . . . . . . . . . . . . . . . . . . . . . . 107
5.5.3 Dynamic Scope: Association Lists and CRT . . . . . . . . . 109
5.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 113
5.7 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
5.8 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 114
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 116
6 Control Structure . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117
6.1 Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
6.1.1 Expression Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 118
6.1.2 Semantics of Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 120
6.1.3 Evaluation of Expressions . . . . . . . . . . . . . . . . . . . . . . . . . . . 123
Contents xvii

6.2 The Concept of Command . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127


6.2.1 The Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 128
6.2.2 Assignment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129
6.3 Sequence Control Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 134
6.3.1 Commands for Explicit Sequence Control . . . . . . . . . . . . 135
6.3.2 Conditional Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 137
6.3.3 Iterative Commands . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 141
6.4 Structured Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 148
6.5 Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 151
6.5.1 Tail Recursion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 153
6.5.2 Recursion or Iteration? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 157
6.6 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 158
6.7 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
6.8 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 159
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 161
7 Control Abstraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 163
7.1 Subprograms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 164
7.1.1 Functional Abstraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 166
7.1.2 Parameter Passing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 167
7.2 Higher-Order Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 176
7.2.1 Functions as Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 177
7.2.2 Functions as Results . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 182
7.2.3 Anonymous Functions: Lambda Expressions . . . . . . . . . 185
7.3 Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 187
7.3.1 Implementing Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . 192
7.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 193
7.5 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 194
7.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 195
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 197
8 Structuring Data . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
8.1 Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 199
8.1.1 Types as Support for Conceptual Organisation . . . . . . . 200
8.1.2 Types for Correctness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 201
8.1.3 Types and Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . 202
8.2 Type Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 203
8.2.1 Static and Dynamic Checking . . . . . . . . . . . . . . . . . . . . . . . 204
8.3 Scalar Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 205
8.3.1 Booleans . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 206
8.3.2 Characters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
8.3.3 Integers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
8.3.4 Reals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 207
8.3.5 Fixed Point . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 208
8.3.6 Complex . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
8.3.7 Unit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 209
xviii Contents

8.3.8 Enumerations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210


8.3.9 Intervals . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 210
8.3.10 Ordered Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
8.4 Composite Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
8.4.1 Records . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 211
8.4.2 Unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 213
8.4.3 Tagged Unions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 215
8.4.4 Arrays . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 216
8.4.5 Sets . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 221
8.4.6 Pointers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 222
8.4.7 Sequences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 226
8.4.8 Recursive Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 228
8.4.9 Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 230
8.5 Equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 231
8.5.1 Equivalence by Name . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
8.5.2 Structural Equivalence . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 232
8.6 Compatibility and Conversion . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 234
8.7 Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 238
8.7.1 Overloading . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 239
8.7.2 Universal Parametric Polymorphism . . . . . . . . . . . . . . . . . 240
8.7.3 Subtype Universal Polymorphism . . . . . . . . . . . . . . . . . . . . 242
8.7.4 Remarks on the Implementation . . . . . . . . . . . . . . . . . . . . . 243
8.8 Type Checking and Inference . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 245
8.9 Safety: An Assessment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 247
8.10 Avoiding Dangling References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
8.10.1 Tombstone . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 248
8.10.2 Locks and Keys . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 250
8.11 Garbage Collection . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 251
8.11.1 Reference Counting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 252
8.11.2 Mark and Sweep . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 254
8.11.3 Interlude: Pointer Reversal . . . . . . . . . . . . . . . . . . . . . . . . . . . 255
8.11.4 Mark and Compact . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 256
8.11.5 Copy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 257
8.12 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
8.13 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 260
8.14 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 261
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 264
9 Data Abstraction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 267
9.1 Abstract Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 268
9.2 Information Hiding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 270
9.2.1 Representation Independence . . . . . . . . . . . . . . . . . . . . . . . . 273
9.3 Modules . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 274
9.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
9.5 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 276
Contents xix

9.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278


References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 278
10 Object-Oriented Paradigm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 279
10.1 The Limits of Abstract Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . 280
10.1.1 A First Review . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
10.2 Fundamental Concepts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 283
10.2.1 Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 284
10.2.2 Classes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 286
10.2.3 Encapsulation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
10.2.4 Subtypes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 289
10.2.5 Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 295
10.2.6 Dynamic Method Lookup . . . . . . . . . . . . . . . . . . . . . . . . . . . 300
10.3 Implementation Aspects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 305
10.3.1 Single Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 306
10.3.2 The Problem of Fragile Base Class . . . . . . . . . . . . . . . . . . 308
10.3.3 Dynamic Method Dispatch in the JVM . . . . . . . . . . . . . . 309
10.3.4 Multiple Inheritance . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 312
10.4 Polymorphism and Generics . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
10.4.1 Subtype Polymorphism . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 318
10.4.2 Generics in Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 320
10.4.3 Implementation of Generics in Java . . . . . . . . . . . . . . . . . . 325
10.4.4 Generics, Arrays and Subtype Hierarchy . . . . . . . . . . . . . 325
10.4.5 Covariant and Contravariant Overriding . . . . . . . . . . . . . . 327
10.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 330
10.6 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
10.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 331
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 334
11 Functional Programming Paradigm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
11.1 Computing Without State . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 335
11.1.1 Expressions and Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . 336
11.1.2 Computation as Reduction . . . . . . . . . . . . . . . . . . . . . . . . . . . 338
11.1.3 The Fundamental Ingredients . . . . . . . . . . . . . . . . . . . . . . . . 340
11.2 Evaluation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
11.2.1 Values . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 341
11.2.2 Capture-Free Substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
11.2.3 Evaluation Strategies . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 342
11.2.4 Comparison of the Strategies . . . . . . . . . . . . . . . . . . . . . . . . 345
11.3 Programming in a Functional Language . . . . . . . . . . . . . . . . . . . . . . 347
11.3.1 Local Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
11.3.2 Interactiveness . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 347
11.3.3 Pattern Matching . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 348
11.3.4 Programming in a Functional Style . . . . . . . . . . . . . . . . . . 349
11.3.5 Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 350
11.3.6 Infinite Objects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 352
xx Contents

11.3.7 Imperative Aspects . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 353


11.4 An Assessment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 355
11.5 Implementation: The SECD Machine . . . . . . . . . . . . . . . . . . . . . . . . 356
11.6 Fundamentals: The λ-Calculus . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 359
11.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 365
11.8 Bibliographical Note . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
11.9 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 366
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 367
12 Logic Programming Paradigm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
12.1 Deduction as Computation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 369
12.1.1 An Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 370
12.2 Syntax . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 373
12.2.1 The Language of First-Order Logic . . . . . . . . . . . . . . . . . . 373
12.2.2 Logic Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 375
12.3 Theory of Unification . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
12.3.1 The Logic Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 377
12.3.2 Substitution . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 378
12.3.3 Most General Unifier . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 381
12.3.4 A Unification Algorithm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 383
12.4 The Computational Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
12.4.1 The Herbrand Universe . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 386
12.4.2 Declarative and Procedural Interpretation . . . . . . . . . . . . 387
12.4.3 Procedure Calls . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 388
12.4.4 Control: Non-determinism . . . . . . . . . . . . . . . . . . . . . . . . . . . 392
12.4.5 Some Examples . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 394
12.5 Extensions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
12.5.1 Prolog . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 397
12.5.2 Logic Programming and Databases . . . . . . . . . . . . . . . . . . 402
12.6 Advantages and Disadvantages of the Logic Paradigm . . . . . . . . 403
12.7 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 404
12.8 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 405
12.9 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 406
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 407
13 Constraint Programming Paradigm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
13.1 Constraint Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 409
13.1.1 Types of Problems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 411
13.2 Constraint Logic Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 413
13.2.1 Syntax and Semantics of Clp . . . . . . . . . . . . . . . . . . . . . . . 414
13.3 Generate and Test Versus Constraint and Generate . . . . . . . . . . . . 417
13.3.1 A Further Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 420
13.4 MiniZinc . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
13.4.1 A MiniZinc Csp Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 422
13.4.2 A MiniZinc Cop Model . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 425
13.5 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427
Contents xxi

13.6 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 427


13.7 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 428
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 431
14 Concurrent Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
14.1 Threads and Processes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 433
14.2 A Brief Historical Overview . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 434
14.3 Types of Concurrent Programming . . . . . . . . . . . . . . . . . . . . . . . . . . . 436
14.3.1 Communication Mechanisms . . . . . . . . . . . . . . . . . . . . . . . . 438
14.3.2 Synchronisation Mechanisms . . . . . . . . . . . . . . . . . . . . . . . . 440
14.4 Shared Memory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 441
14.4.1 Busy Waiting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 442
14.4.2 Scheduler-Based Synchronisation . . . . . . . . . . . . . . . . . . . . 445
14.5 Message Exchange . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
14.5.1 Naming Mechanisms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 451
14.5.2 Asynchronous Communication . . . . . . . . . . . . . . . . . . . . . . 453
14.5.3 Synchronous Communication . . . . . . . . . . . . . . . . . . . . . . . . 456
14.5.4 Remote Procedure Call and Rendez-Vous . . . . . . . . . . . . 457
14.6 Non-determinism and Parallel Composition . . . . . . . . . . . . . . . . . . 459
14.6.1 Parallel Composition . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 462
14.7 Concurrency in Java . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
14.7.1 Creation of Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 463
14.7.2 Scheduling and Termination of Threads . . . . . . . . . . . . . . 464
14.7.3 Synchronisation and Communication Between
Threads . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 466
14.8 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
14.9 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 469
14.10 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 470
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 471
15 Service-Oriented Programming Paradigm . . . . . . . . . . . . . . . . . . . . . . . . . . 473
15.1 Towards Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
15.1.1 Distributed Programs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 473
15.1.2 Open Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 474
15.1.3 Loose Coupling and Interoperability . . . . . . . . . . . . . . . . . 475
15.1.4 Approaching Services . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 476
15.2 Elements of Service-Oriented Programming . . . . . . . . . . . . . . . . . . 477
15.2.1 Services, a Layered View . . . . . . . . . . . . . . . . . . . . . . . . . . . . 477
15.2.2 Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 481
15.2.3 Messaging Patterns . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 487
15.2.4 Operations and Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . 489
15.2.5 Behaviour . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 494
15.3 Service-Oriented Architectures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 509
15.3.1 The First Generation: Web Services . . . . . . . . . . . . . . . . . . 510
15.3.2 Second Generation: Microservices and Serverless . . . . 513
15.4 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515
xxii Contents

15.5 Bibliographical Note . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 515


15.6 Exercises . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 516
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 517
16 Short Historical Perspective . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
16.1 Beginnings . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 519
16.2 Factors in the Development of Languages . . . . . . . . . . . . . . . . . . . . 522
16.3 1950s and 1960s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 523
16.4 1970s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 527
16.5 1980s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 532
16.6 1990s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 536
16.7 2000s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 542
16.8 2010s . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 544
16.9 Summary . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 547
16.10 Bibliographical Notes . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548
References . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 548

Index . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 551
Abstract Machines
1

Abstraction mechanisms play a crucial role in computing because they allow us


to deal with the complexity inherent in most computational systems by isolating
the aspects that are important in a particular context. In the field of programming
languages, these mechanisms are fundamental, both from a theoretical point of view
(many important concepts can be adequately formalised using abstractions) and
in a practical sense, because because programming languages today use common
abstraction-creating constructs.
One of the most general concepts is the abstract machine. In this chapter, we
will see how this concept is closely related to programming languages. Abstract
machines allow describing what an implementation of a programming language is,
without requiring us to go into the specific details of any particular implementation.
We will describe in general terms what is the interpreter and the compiler for a
language. Finally, will see how abstract machines can be structured in hierarchies
that describe and implement complex software systems.

1.1 The Concepts of Abstract Machine and the Interpreter

In the context of this book, the term “machine” refers clearly to a computing machine.
An electronic, digital computer is a physical machine that executes suitably formal-
ized algorithms so that the machine can “understand” them. Intuitively, an abstract
machine is an abstraction of the concept of a physical computer.
For actual execution, algorithms must be appropriately formalised using the con-
structs provided by a programming language. In other words, the algorithms we want
to execute must be represented using the instructions of a programming language,
L . This language will be formally defined in terms of a specific syntax and a precise
semantics—see Chap. 2. For the time being, the nature of L is of no concern to us.

© The Author(s), under exclusive license to Springer Nature Switzerland AG 2023 1


M. Gabbrielli and S. Martini, Programming Languages: Principles and Paradigms,
Undergraduate Topics in Computer Science,
https://doi.org/10.1007/978-3-031-34144-1_1
2 1 Abstract Machines

Interpreter

Sequence
Data control

Memory Data Operations


control

Program
Memory
management

Fig. 1.1 The structure of an abstract machine

Here, it is sufficient to know that the syntax of L allows us to use a given finite set of
constructs, called instructions, to construct programs. A program in L (or program
written in L ) is a finite, ordered list of instructions of L . With these preliminary
remarks, we now present a definition that is central to this chapter.

Definition 1.1 (Abstract Machine) Assume that we are given a programming lan-
guage, L . An abstract machine for L , denoted by ML , is any set of data structures
and algorithms which can perform the storage and execution of programs written
in L .

When we choose not to specify the language, L , we will simply talk of the
abstract machine, M , omitting the subscript. We will soon see some example abstract
machines and how they can actually be implemented. For the time being, let us
consider the structure of an abstract machine. As depicted in Fig. 1.1, a generic
abstract machine ML is composed of a store and an interpreter. The store serves
to save data and programs while the interpreter is the component that executes the
instructions of the programs.

1.1.1 The Interpreter

Any interpreter is specific to its language. However, there are types of operation and
an “execution method” common to all interpreters. The type of operation executed
by the interpreter and associated data structures, fall into the following categories:
1.1 The Concepts of Abstract Machine and the Interpreter 3

1. Operations for processing primitive data;


2. Operations and data structures for controlling the sequence of execution of oper-
ations;
3. Operations and data structures for controlling data transfers;
4. Operations and data structures for memory management.

We consider these four points in detail.


1. The need for operations processing primitive data is clear. The purpose of
an (abstract) machine is the execution of algorithms, so it must have operations
for manipulating primitive data items, that is data that have a direct representation
in the machine. For example, for physical abstract machines, as well as for the
abstract machines for most programming languages, numbers (integer or real) are
almost always primitive data. The machine directly implements the various opera-
tions required to perform arithmetic (addition, multiplication, etc.). These arithmetic
operations are therefore primitive operations as far as the abstract machine is con-
cerned.1
2. Operations and structures for “sequence control” allow controlling the execution
flow of instructions in a program. The normal sequential execution of a program might
have to be modified when some conditions are satisfied. The interpreter, therefore,
makes use of data structures (for example to hold the address of the next instruction
to execute) which are manipulated by specific operations that are different from those
used for data manipulation (for example, operations to update the address of the next
instruction to execute).
3. Operations that control data transfers are included in order to control how
operands and data are to be transferred from memory to the interpreter and vice
versa. These operations deal with the different store addressing modes and the order
in which operands are to be retrieved from the store. In some cases, auxiliary data
structures might be necessary to handle data transfers. For example, some types of
machine use stacks (implemented either in hardware or software) for this purpose.
4. Finally, there is memory management. This concerns the operations used to
allocate data and programs in memory. In the case of abstract machines that are sim-
ilar to hardware machines, storage management is relatively simple. In the limit case
of a physical register-based machine that is not multi-programmed, a program and
its associated data could be allocated in a zone of memory at the start of execution
and remain there until the end, without much real need for memory management.
Abstract machines for common programming languages, instead, use more sophis-
ticated memory management techniques. In fact, some constructs in these languages
cause memory to be allocated or deallocated. Correct implementation of these oper-
ations requires suitable data structures (for example, stacks) and dynamic operations
(which are, therefore, executed at runtime).

1 There exist programming languages, for example, some declarative languages, in which numeric

values and their associated operations are not primitive.


4 1 Abstract Machines

“Low-level” and “High-level” Languages

In the field of programming languages, the terms “low level” and “high level” are often used to
refer to languages “closer the physical machine” and “closer to the human user”, respectively.
Let us therefore call low-level, those languages whose abstract machines are very close to, or
coincide with, the physical machine. Starting at the end of the 1940s, these languages were used
to program the first computers, but, they turned out to be extremely awkward to use. Because the
instructions in these languages had to take into account the physical characteristics of the machine,
matters that were completely irrelevant to the algorithm had to be considered while writing programs,
or in coding algorithms. It must be remembered that often when we speak generically about “machine
language”, we mean the language (a low-level one) of a physical machine. A particular low-level
language for a physical machine is its assembly language, which is a symbolic version of the
language of a hardware machine (that is, which uses symbols such as ADD, MUL, etc., instead of
their associated hardware binary codes). Programs in assembly language are translated into machine
code using a program called an assembler.
So-called high-level programming languages are, on the other hand, those which support
appropriate abstraction mechanisms to ensure that they are independent of the physical character-
istics of the underlying physical computer. High-level languages are therefore suited to expressing
algorithms in ways that are relatively easy for the human user to understand. Clearly, even the
constructs of a high-level language must, at the end, correspond to some sequence of instructions
of the physical machine, because it must be possible to execute those programs.
We will return to these issues, from a historical perspective, in Chap. 16.

The interpreter’s execution cycle, which is substantially the same for all inter-
preters, is shown in Fig. 1.2. It is organised in terms of the following steps. First, it

Start

Fetch
next instruction

Decode

Fetch
operands

Choose

Execute OP1 Execute OP2 Execute OPn Execute HALT

Stop
Store the
risult

Fig. 1.2 The execution cycle of a generic interpreter


1.1 The Concepts of Abstract Machine and the Interpreter 5

fetches the next instruction to execute from memory. The instruction is then decoded
to determine the operation to be performed as well as its operands. As many operands
as required by the instruction are fetched from memory using the method described
above. After this, the instruction, which must be one of the machine’s primitives,
is executed. Once execution of the operation has completed, any results are stored.
Then, unless the instruction just executed is a halt instruction, execution passes to
the next instruction in sequence and the cycle repeats.
Now that we have seen the interpreter, we can define the language it interprets as
follows:

Definition 1.2 (Machine language) Given an abstract machine, ML , the language


L “understood” by ML ’s interpreter is called the machine language of ML .

Programs written in the machine language of ML will be stored in the abstract


machine’s storage structures so that they cannot be confused with other primitive data
on which the interpreter operates (from the interpreter’s viewpoint, programs are also
a kind of data). Given that the internal representation of the programs executed by the
machine ML is usually different from its external representation, then we should
strictly talk about two different languages. In any case, in order not to complicate
notation, for the time being we will not consider such differences and therefore we
will speak of just one machine language, L , for machine ML .

1.1.2 An Example of an Abstract Machine: The Hardware Machine

It should be clear that the concept of abstract machine can be used to describe a
variety of different systems, ranging from physical machines right up to the World
Wide Web.
As a first example of an abstract machine, let us consider the concrete case of a
conventional physical machine such as that in Fig. 1.3, physically implemented using
logic gates and electronic components. Let us call such a machine M HL H and let
L H be its machine language. We may describe its components as follows.

Memory
The storage component of a physical computer is composed of various levels of
memory. Secondary memory implemented using optical or magnetic components;
primary memory, organised as a linear sequence of cells, or words, of fixed size
(usually a multiple of 8 bits, for example, 32 or 64 bits); cache and the registers
which are internal to the Central Processing Unit (CPU).
Physical memory, whether primary, cache, or register file, permits the storage of
data and programs. As stated, this is done using the binary alphabet.
Data is divided into a few primitive “types”: usually, we have integer numbers,
so-called “real” numbers (in reality, a subset of the rationals), characters, and fixed-
length sequences of bits. Depending upon the type of data, different physical repre-
sentations, which use one or more memory words for each element of the type are
6 1 Abstract Machines

PC UC R1 ... RN

IR ALU

MAR MDR

Main memory

Fig. 1.3 The structure of a conventional computer

used. For example, the integers can be represented by 1 s or 2 s complement num-


bers contained in a single word, while reals have to be represented as floating point
numbers using one or two words depending on whether they are single or double
precision. Alphanumeric characters are also implemented as sequences of binary
numbers encoded in an appropriate representational code (for example, the ASCII
or UNI CODE formats).
We will not here go into the details of these representations since they will be
examined in more detail in Chap. 8. We must emphasise the fact that although all
data is represented by sequences of bits, at the hardware level we can distinguish
different categories, or more properly types, of primitive data that can be manipulated
directly by the operations provided by the hardware. For this reason, these types are
called predefined types.

The Language of the Physical Machine


The language, L H which the physical machine executes is composed of relatively
simple instructions. A typical instruction with two operands, for example, requires
one word of memory and has the format:
OpCode Operand1 Operand2

where OpCode is a unique code that identifies one of the primitive operations defined
by the machine’s hardware, while Operand1 and Operand2 are values that allow
the operands to be located by referring to the storage structures of the machine and
their addressing modes. For example,
ADD R5 , R0

might indicate the sum of the contents of registers R0 and R5, with the result being
stored in R5, while
ADD ( R5 ) , ( R0 )
1.1 The Concepts of Abstract Machine and the Interpreter 7

might mean that the sum of the contents of the memory cells whose addresses are
contained in R0 and R5 is computed and the result stored in the cell whose address
is in R5. In these examples, for reasons of clarity, we are using symbolic codes
such as ADD, R0, (R0). In the language under consideration, on the other hand, we
have binary numeric values (addresses are expressed in “absolute” mode). From the
viewpoint of internal representation, instructions are nothing more than data stored
in a particular format.
Like the instructions and data structures used in executing programs, the set of pos-
sible instructions (with their associated operations and addressing modes) depends
on the particular physical machine. It is possible to discern classes of machine with
similar characteristics. For example, we can distinguish between conventional CISC
(Complex Instruction Set Computer) processors which have many machine instruc-
tions (some of which are quite complex) and RISC (Reduced Instruction Set Comput-
ers) architectures in which there tend to be fewer instructions which are, in particular,
simple enough to be executed in a few (possibly one) clock cycle and in pipelined
fashion.

Interpreter
With the general structure of an abstract machine as a model, it is possible to identify
the following components of a physical (hardware) machine:

1. The operations for processing primitive data are the usual arithmetic and logi-
cal operations. They are implemented by the ALU (Arithmetic and Logic Unit).
Arithmetic operations on integers, and floating-point numbers, booleans are pro-
vided, as are shifts, tests, etc.
2. For sequence control, the main data structure is the Program Counter (PC) register,
which contains the address of the next instruction to execute. Sequence-control
operations specifically use this register and typically include the increment oper-
ation (which handles the normal flow of control) and operations that modify the
value stored in the PC register (jumps).
3. To handle data transfer, the CPU registers interfacing with the main memory are
used. They are: the data address register (the MAR or Memory Address Register)
and the data register (MDR or Memory Data Register). There are, in addition,
operations that modify the contents of these registers and that implement various
addressing modes (direct, indirect, etc.). Finally, there are operations that access
and modify the CPU’s internal registers.
4. Memory processing depends on the specific architecture. In the simplest case of
a register machine that is not multi-programmed, memory management is rudi-
mentary. The program is loaded and immediately starts executing; it remains in
memory until it terminates. To increase computation speed, all modern architec-
tures use more sophisticated memory management techniques. In the first place,
there are several levels of memory between registers and main memory (i.e., cache
memory), whose management needs special data structures and algorithms. Sec-
ond, some form of multi-programming is almost always implemented (the exe-
8 1 Abstract Machines

cution of a program can be suspended to give the CPU to other programs, so as


to optimise the management of resources). As a general rule, these techniques
(which are used by operating systems) usually require specialised hardware sup-
port to manage the presence of more than one program in memory at any time
(for example, dynamic address relocation).
All the techniques so far described need specific memory-management data struc-
tures and operations to be provided by the hardware. In addition, there are other
types of machine that correspond to less conventional architectures. In the case
of a machine which uses a (hardware) stack instead of registers, there is the stack
data structure together with the push and pop operations.

The interpreter for the hardware machine is implemented as a set of physical


devices which comprise the Control Unit and which support execution of the so-
called fetch-decode-execute cycle, using the sequence control operations. This cycle
is analogous to that in the generic interpreter such as the one depicted in Fig. 1.2. It
consists of the following phases.
In the fetch phase, the next instruction to be executed is retrieved from memory.
This is the instruction whose address is held in the PC register (the PC register is
automatically incremented after the instruction has been fetched). The instruction,
which is formed of an operation code and perhaps some operands, is then stored in
a special register, called the instruction register.
In the decode phase, the instruction stored in the instruction register is decoded
using special logic circuits. This allows the correct interpretation of both the instruc-
tion’s operation code and the addressing modes of its operands. The operands are
then retrieved by data transfer operations using the address modes specified in the
instruction.
Finally, in the execute phase, the primitive hardware operation is actually exe-
cuted, for example using the circuits of the ALU if the operation is an arithmetic or
logical one. If there is a result, it is stored in the way specified by the addressing
mode and the operation code currently held in the instruction register. Storage is
performed by means of data-transfer operations. At this point, the instruction’s exe-
cution is complete and is followed by the next phase, in which the next instruction is
fetched and the cycle continues (provided the instruction just executed is not a stop
instruction).
Note that at any given moment the hardware machine distinguishes data from
instructions. At the physical level, there is no distinction between them, given that
they are both represented as bit sequences. The distinction is contextual and derives
from the state of the CPU. In the fetch state, every word fetched from memory is
considered an instruction, while in the execute phase, it is considered to be data.
An accurate description of the operation of the physical machine would require the
introduction of other states in addition to fetch, decode and execute. Our description
only aims to show how the general concept of an interpreter is instantiated by a
physical machine.
1.2 Implementation of a Language 9

1.2 Implementation of a Language

An abstract machine, ML , is by definition a device which allows the execution of


programs written in L . An abstract machine therefore corresponds uniquely to a
language, its machine language. Conversely, given a programming language, L ,
there are several (an infinite number of) abstract machines that have L as their
machine language. These machines differ from each other in the way in which the
interpreter is implemented and in the data structures that they use. They all agree,
though, on the language they interpret—L .
To implement a programming language L means realising an abstract machine
which has L as its machine language. Before seeing which implementation tech-
niques are used for current programming languages, we first discuss the various
theoretical possibilities.

1.2.1 Implementation of an Abstract Machine

Any actual implementation of an abstract machine, ML will sooner or later use


some kind of physical device (mechanical, electronic, biological, etc.) to execute the
instructions of L . The use of such a device, nevertheless, can be explicit or implicit.
We may give a “physical” implementation (in hardware) of ML ’s constructs. But
we may also realise implementations (in software or firmware) at levels intermediate
between ML and an underlying physical device. We can therefore reduce the various
options for implementing an abstract machine to the following three cases and to
combinations of them:

• implementation in hardware;
• simulation using software;
• simulation (emulation) using firmware.

Implementation in Hardware
The direct implementation of ML in hardware is always possible in principle and
is conceptually fairly simple. It is, in fact, a matter of using physical devices such as
memory, arithmetic and logic circuits, buses, etc., to implement a physical machine
whose machine language coincides with L . To do this, it is sufficient to implement in
the hardware the data structures and algorithms constituting the abstract machine.2
The implementation of a machine ML in hardware has the advantage that the
execution of programs in L will be fast because they will be directly executed by the
hardware. This advantage, nevertheless, is compensated for by various disadvantages
which predominate when L is a generic high-level language. Indeed, the constructs
of a high-level language, L , are relatively complicated and far from the elementary

2 Chapter 3 will tackle the question of why this can always be done for programming languages.
Another random document with
no related content on Scribd:
and pillaged the inhabitants of their cattle, hogs, sheep, poultry, and,
in short, of anything they could lay their hands upon. It was no
uncommon thing of an afternoon to see a farmer driving a flock of
turkeys, geese, ducks, or dunghill fowls and locking them up in his
cellar for security at night.... It was no uncommon thing for a farmer,
his wife and children to sleep in one room, while his sheep were
bleating in the room adjoining, his hogs grunting in the kitchen, and
the cocks crowing, hens cackling, ducks quacking, and geese
hissing in the cellar.... This robbing was done by people sent to
America to protect loyalists against the persecutions and
depredations of rebels. To complain was needless; the officers
shared in the plunder.” In Newtown, a Hessian soldier opened a
butcher’s shop, where he undersold all competitors, because while
they had to pay for their meat he had no such outlay. In 1781, when
the troops left Flushing, a resident of that place wrote, “There was
not a four-footed animal (a few dogs excepted) left in Flushing, nor a
wooden fence.”
We cannot wonder at the indignant words with which Mr. Jones
closes his recital of this vandalism. “If Great Britain had, instead of
governing by military law, by courts of police, and courts martial,
revived the civil law, opened the courts of justice, invested the civil
magistrates with their full power, and convened general assemblies
in New York, New Jersey, Pennsylvania, Rhode Island, Virginia, and
in South and North Carolina (as well as in Georgia, where it
produced the most salutary effects), as the rebels abandoned these
provinces and fled before the British arms; and prevented, by
severely punishing, all kinds of plunder, rapine, and pillage
committed by the army, the rebellion in all probability would have
terminated in a different manner. The empire would not have been
disgraced or dishonored, nor Great Britain reduced to the necessity
of asking pardon of her ungrateful children, acknowledging herself in
the wrong, and granting them absolute, unconditional independence.
But, alas! the very reverse of this marked every step in the royal
army in all its proceedings, and Great Britain, as well as the
Independent States of America, feel to this day the dire effects of a
conduct so very impolitic, so unmilitary, so unjustifiable, and so
repugnant to the Constitution, the spirit, the honor, and the
169
sentiments of Englishmen.
And now let us inquire how the loyalists were treated by the new
governments of the various states. Besides the irregular violence to
which the unfortunate loyalists were exposed at the hands of Sons of
Liberty and town committeemen, they were marked out for
punishment and plunder by the new state governments as they
came into existence. The State of Massachusetts proscribed three
hundred and eight persons by name, whom it condemned, if ever
found within its borders, to imprisonment and eventual banishment;
and if they ventured to return, it denounced the death penalty upon
them. Not all of these were the wealthy merchants and lawyers who
had offended the populace by their addresses to Hutchinson and
Gage; at least a fifth of the number were from the middle classes of
society, and some of them were of still humbler position. The State of
New Hampshire, small as its population was at that time, banished
seventy-six by name and confiscated twenty-eight estates. New York
attainted and confiscated the property of fifty-nine persons by name,
three of whom were women whose chief offence lay in the
attractiveness of their estates. Pennsylvania summoned sixty-two
persons to surrender themselves for trial for treason, and on their
failing to appear they were pronounced attainted, and thirty-six
estates were confiscated. In Delaware the property of forty-six
refugees was confiscated. In North Carolina, sixty-five estates were
confiscated. In South Carolina, for the offence of attachment to the
royal cause in different degrees of offensiveness, two hundred and
fifteen persons were either fined twelve per cent. of their entire
170
property, or deprived of it wholly, or banished from the country. In
Rhode Island, death and confiscation of estate were the
punishments provided by law for any person who communicated with
the ministry or their agents, afforded supplies to their forces, or
piloted the armed ships of the king; and certain persons were
pronounced by name enemies to liberty, and their property forfeited
in consequence. In Connecticut, where the loyalists were very
numerous but inclined to be quiet if they were let alone, these
offences only involved loss of estate and of liberty for a term not
exceeding three years; but to speak, write, or act against the doings
of Congress or the Assembly of Connecticut was punishable by
disqualification from office, imprisonment, and the disarming the
offender. The estates of those who sought the royal fleets or land
forces for shelter might, by law, be seized and confiscated. In her
treatment of loyalists Connecticut showed the same shrewd sense
that had characterized the proceedings of that republic from its
earliest days; and the result was seen in the fact that the loyalists,
instead of being alienated, became after the war was over some of
her best and most patriotic citizens. William Samuel Johnson, who
during part of the war, at least, was under surveillance as a
suspected Tory, but who when the war was over was one of
Connecticut’s delegates to the Constitutional Convention of 1787,
and Seabury, the author of the clever and exasperating “A. W.
Farmer” letters, who had been pulled through the mud by Sons of
Liberty at New Haven, were none the less loyal citizens of the
commonwealth and of the nation, and none the less respected by
men who had differed from them, because they had been loyal to
their convictions of duty. In Massachusetts, the feeling was much
more bitter, and, in addition to the special act already mentioned, any
person suspected of enmity to the Whig cause might be arrested
under a magistrate’s warrant and banished, unless he would swear
fealty to the friends of liberty; and the selectmen of towns could
prefer in town meeting charges of political treachery and the
individual thus accused, if convicted by a jury, could be sent into the
enemy’s jurisdiction. By a second special act the property of twenty-
nine persons, “notorious conspirators,” was confiscated; of these,
fifteen had been “mandamus” councillors; two, governors of the
province; one, lieutenant-governor; one, treasurer; one, secretary;
one, attorney-general; one, chief-justice; and four, commissioners of
customs. The State of Virginia, though passing no special acts,
passed a resolution that persons of a given description should be
deemed and treated as aliens, and that their property should be sold
and the proceeds go into the public treasury for future disposal. In
New York, the county commissioners were authorized to apprehend
and decide upon the guilt of such inhabitants as were supposed to
hold correspondence with the enemy or who had committed some
other specified acts, and might punish those whom they adjudged to
be guilty with imprisonment for three months or banishment for
seven years. Persons opposed to liberty and independence were
prohibited from the practice of law in the courts; and any parent
whose sons went off and adhered to the enemy was subject to a tax
of ninepence in the pound value of such parent’s estate for each and
every such son.
The Congress naturally left such matters largely to the individual
states, but nevertheless passed a resolution subjecting to martial law
and death all who should furnish provisions, etc., to the British army
in New Jersey, Pennsylvania, and Delaware, and resolved that all
loyalists taken in arms should be sent to the states to which they
171
belonged, there to be dealt with as traitors.
In regard to this subject of legal attainder and exile, Mr. Sabine
remarks very moderately and sensibly: “Nor is it believed that either
the banishment, or the confiscation laws, as they stood, were more
expedient than just. The latter did little towards relieving the public
necessities, and served only to create a disposition for rapacity, and
to increase the wealth of favored individuals. Had the estates, which
were seized and sold, been judiciously or honestly managed, a
considerable sum would have found its way to the treasury; but, as it
was, the amount was inconsiderable, some of the wisest and purest
Whigs of the time hung their heads in shame, because of the
passage of measures so unjustifiable, and never ceased to speak of
them in terms of severe reprobation. Mr. Jay’s disgust was
unconquerable, and he never would purchase any property that had
172
been forfeited under the Confiscation Act of New York.”
Curwen, a Salem loyalist who was allowed to return after the
war, writes in terms that, though exaggerated, yet describe the result
upon public morals of the confiscations:
“So infamously knavish has been the conduct of the
commissioners, that though frequent attempts have been made to
bring them to justice, and respond for the produce of the funds
resting in their hands, so numerous are the defaulters in that august
body, the General Court, that all efforts have hitherto proved in vain.
Not twopence in the pound have arrived to the public treasury of all
173
the confiscations.”
It only now remains to notice the treatment the unfortunate
loyalists received from their friends in England and the manner in
which the British government—for which they had sacrificed home,
friends, and property, and had embraced exile, contempt, and
penury—threw them upon the tender mercies of their opponents in
the treaty of peace. This surrender of their interests by Lord
Shelburne called out, in both Houses of the Parliament, expressions
of sympathetic indignation; but the sympathy never took any material
shape. Sheridan, in the House of Commons, execrated the treatment
of these unfortunate men, “who, without the least notice taken of
their civil and religious rights, were handed over as subjects to a
power that would not fail to take vengeance on them for their zeal
and attachment to the religion and government of the ‘mother
country.’” In the House of Lords, Lord Loughborough said, “that
neither in ancient nor modern history had there been so shameful a
desertion of men who had sacrificed all to their duty and to their
reliance upon British faith.”
To such charges Lord Shelburne could only reply by a feeble
appeal to the mercy of his condemners: “I have but one answer to
give the House; it is the answer I give my own bleeding heart. A part
must be wounded that the whole of the empire may not perish. If
better terms could be had, think you, my lords, that I would not have
embraced them? I had but the alternative either to accept the terms
174
proposed or continue the war.”
Lord Shelburne’s statement was correct. He had entered upon
the negotiations for peace full of sympathy for the loyalists and
resolved to make their cause the cause of England; but when, to his
attempts to obtain for them the restoration of their property and the
abolition of penal laws, was opposed a steady non possumus, his
enthusiasm for his persecuted fellow-countrymen waned; and when
at last it was plainly suggested to him that a year’s prolongation of
the war would cost more than all the loyalists’ property put together,
he consented to accept the assurance, the futility and emptiness of
which was evident upon the face of it, that “Congress shall earnestly
recommend” to the several states to repeal the laws of attainder and
confiscation which had been passed against the Tories and their
property. One of the American negotiators brusquely remarked that it
was better and more proper that the loyalists should be
compensated by their friends than by their enemies. This desertion
of their interests almost broke the hearts of some of the best and
most public-spirited of the loyalists, who had given up everything for
the cause of their country, and now saw themselves consigned to
poverty in their old age, or at the best to supplicating aid of the
British government and being exposed to all “the insolence of office
175
and the scorns that patient merit of the unworthy takes.”
It took a long time to adjust the claims and to distribute the
bounty which was doled out by unwilling officials. It was 1783 when
the war closed, but not until 1790 was the indemnity paid out to the
claimants; and then England forced her unfortunate pensioners,
made paupers by their trust in her, to accept about £3,300,000 for
losses reckoned at over £8,000,000. It is estimated that over a
thousand claimants had in the mean time perished in want and
penury. Those were on the whole more fortunate, as events proved,
who had braved it out in America than were those who had trusted to
176
the gratitude of England.
What was the loss of America was the gain to her nearest
neighbors, the coast provinces of New Brunswick and Nova Scotia.
As early as 1775 the exodus from Boston to Halifax had begun; and
when Howe evacuated the city, a large number of loyalists took
refuge with the fleet and army, and leaving all behind came to Halifax
to seek their fortunes under another sky. From that time on,
throughout the war, Halifax was the haven of refuge for persecuted
177
loyalists. At the evacuation of New York and Savannah no fewer
than 30,000 persons left the United States for Nova Scotia. Halifax
was so crowded that houses could not be had at any price, and
178
provisions were held at famine prices. From northern New York
and Vermont the loyalists crossed over into Upper Canada and laid
the foundation of that prosperous province under the vigorous
government of Governor Simcoe, who during the war had
commanded a regiment of loyalist rangers which had done efficient
179
service. With many a suffering, many a privation, these exiles for
conscience’ sake toiled to make homes for themselves in the
wilderness, and it is to them that the development of those provinces
is due. Familiar New England names meet one at every turn in these
provinces, especially in Nova Scotia. Dr. Inglis of Trinity Church, New
York, was the first bishop, and Judge Sewall of Massachusetts, the
first chief justice there. The harshness of the laws and the greed of
the new commonwealths thus drove into exile men who could be ill
spared, and whose absence showed itself in the lack of balance and
of political steadiness that characterized the early history of the
Republic. This, moreover, perpetuated a traditional dislike, grudge,
and suspicion between the people of the United States and their
nearest neighbors, men of the same blood and the same speech;
while the new-founded colonies, composed almost exclusively of
conservatives, were naturally slow, if sure, in their development.
This dislike and suspicion is now fortunately diminishing with the
lapse of years, but it was a great pity it ever was created. The men
who were willing to give up home, friends, and property for an idea,
are not men to be despised or laughed at, as was the fashion of the
generation which roared with delight over the coarse buffooneries of
Trumbull’s McFingal. They are rather men for us to claim with pride,
and to honor as Americans, Americans who were true to their
convictions of duty, confessors for their political faith.
Sabine relates the following conversation:
“‘Why did you come here, when you and your associates were
almost certain to endure the sufferings and absolute want of shelter
and food which you have now narrated?’ asked an American
gentleman of one of the first settlers of St. John, New Brunswick, a
man whose life ... was without a stain. ‘Why did we come here?’
replied he, with emotion that brought tears;—‘for our loyalty; think
you that our principles were not as dear to us as were yours to
180
you?’”
NOTES.
152
Franklin’s Memoirs (London, 1818, p. 201), (Sparks, p. 176).
“In 1754, war with France being again apprehended, a
congress of commissioners from the different colonies was by
an order of the lords of trade to be assembled in Albany; there
to confer with the chiefs of the six nations, concerning the
means of defending both their country and ours.
We met the other commissioners at Albany about the middle
of June. In our way thither I projected and drew up a plan for
the union of all the colonies under one government, so far as
might be necessary for defence, and other important general
purposes. As we passed through New York, I had there shown
my project to Mr. James Alexander and Mr. Kennedy, two
gentlemen of great knowledge in public affairs, and being
fortified by their approbation, I ventured to lay it before the
congress. It then appeared that several of the commissioners
had formed plans of the same kind. A previous question was
first taken, whether a union should be established, which
passed in the affirmative, unanimously. A committee was then
appointed, one member from each colony, to consider the
several plans and report. Mine happened to be preferred, and
with a few amendments was accordingly reported. By this plan
the general government was to be administered by a President
General appointed and supported by the Crown; and a grand
Council to be chosen by the representatives of the people of
the several colonies met in their respective assemblies. The
debates upon it in congress went on daily hand in hand with
the Indian business. Many objections and difficulties were
started, but at length they were all overcome, and the plan was
unanimously agreed to, and copies ordered to be transmitted
to the board of trade and to the assemblies of the several
provinces. Its fate was singular: the assemblies did not adopt
it, as they all thought there was too much prerogative in it; and
in England it was judged to have too much of the democratic.
The different and contrary reasons of dislike to my plan make
me suspect that it was really the true medium: and I am still of
opinion it would have been happy for both sides if it had been
adopted. The colonies so united would have been sufficiently
strong to have defended themselves: there would then have
been no need of troops from England; of course the
subsequent pretext for taxing America, and the bloody contest
it occasioned, would have been avoided.”
The plan proposed may be found in Franklin’s Works
(Sparks, i. 36), (London, 1833, v. 299); N. Y. Col. Doc., vi. 889.
The proceedings of the Congress in N. Y. Col. Doc., vi. 853,
other accounts of the Congress by members; Hutchinson, Hist.
Mass. Bay, iii. 19–25; William Smith, History of New York, ii.
180; Stephen Hopkins, A true representation of the plan
formed at Albany (in 1754) for uniting all the British northern
Colonies, in order to their common safety and defence (R. I.
Historical Tracts, No. 9). For an excellent brief statement of the
attempts at consolidation and plans suggested for that
purpose, see Winsor, Narrative and Critical History of the
U. S., v. 611.
153
The Society for the Propagation of the Gospel in Foreign Parts
was founded in 1701. A previous organization bearing a similar
name had been founded during the period of the
Commonwealth, especially for work among the aborigines in
New England, and it is to this association that we owe that
most interesting of missionary relics, Eliot’s Indian Bible. Great
interest was taken in this by the celebrated Robert Boyle, and
scholarships were endowed by Sir Leoline Jenkyns in Jesus
College, Oxford, one condition of which was that the
beneficiary should devote his life after taking his degree to
missionary work in the plantations. The reports of Commissary
Bray, who had been sent out to Maryland, of the spiritual
destitution of the American colonies and of the difficulties
under which the ministers of the Church of England labored,
led to the organization and incorporation of the Society, which
has been from that day to this an active agency in the spread
of religion and knowledge in the colonies of Great Britain.
Humphreys, Historical Account of the Society for the
Propagation of the Gospel. Hawkins, Missions of the Church of
England.
154
For a full account of this most interesting revolution, see E.
Edwards Beardsley, D. D., The History of the Church in
Connecticut. See also Life and Correspondence of Samuel
Johnson, D. D., and Yale College and the Church (History of
the American Episcopal Church, vol. i. 561). Humphreys,
Historical Account, 339.
155
Franklin’s Memoirs, vol. i. pp. 218, 220. An amusing instance
of the prevailing ignorance in regard to American affairs even
among its friends is given by Benjamin Vaughan in a note in
Franklin’s Memoirs, vol. v. p. 320. “To guard against the
incursions of the Indians a plan was sent over to America (and,
as I think, by authority) suggesting the expediency of clearing
away the woods and bushes from a tract of land, a mile in
breadth, and extending along the back of the colonies.” It is
said that this plan was the contribution of Dean Tucker towards
the solution of the Indian problem of the day.
156
Jones, Hist. New York, ii. 291, 559. Political Magazine, Apr.,
1780. Hutchinson, History Mass. Bay, iii. 86–88, 166 note, 254,
293. Hutchinson’s Diary, i. 65. For reasons assigned by
Hutchinson for the patriotism of John Adams, Hist. iii. 297.
157
North American Review, lix. p. 270 (Sabine). “It may be asked,
why, when the oppressions of the mother country were so very
flagrant and apparent, there was not greater unanimity than
appears to have existed; and why a party, so large in numbers,
which in so many colonies included persons so respectable,
and hitherto so universally esteemed, was seemingly, or in
fact, averse to breaking away from British dominion. These
questions have been put to loyalists themselves. They have
answered, that, upon the original formation of parties, they
were generally regarded as the common organizations of the
ins and outs; the one striving to retain, and the other to gain,
patronage and place; and that the mass in taking sides with or
against the royal governors, were stimulated by the hopes
which politicians have always been able to excite in their
followers.”
158
Moore’s Diary of the American Revolution, i. 37–52, 138.
Massachutensis, Letters I., III., IV. Hutchinson, History of
Mass. Bay, iii. passim. A. W. Farmer, The Congress
Canvassed, p. 8. The name Tory was given first in 1763, as a
title of reproach to officers of the crown and such as were for
keeping up their authority. Hist. Mass. Bay, iii. 103.
159
Adams’s Works, ii. 362.
160
For the manner in which the temperate remonstrance of the
loyal colony of New York was treated, see Parliamentary
Register, vol. i. 467–478.
161
A specimen from a comparatively moderate article upon the
loyalists may serve to substantiate the statement of the text
(No. Am. Rev., lxv. p. 142): “The meanest, most dastardly, and
most cruel scenes and deeds of the Revolution were enacted
as the proper fruits of a civil war by a large majority of the
Tories, who remained at home, and who, as regulars, as
volunteers, in gangs, or as individual outlaws, were the
instigators of nearly every foul and atrocious act in the whole
strife. It is from these, the majority of the whole number, that
the name of Tory has received its hateful associations, which
will cling to it to the end of time. A class that includes an Arnold
and a Butler can never hope for complete redemption, at least
so long as Judas remains in ‘his own place.’”
One is glad to appeal from this intemperate and exaggerated
language to the essay upon the loyalists by Dr. George E. Ellis,
in Winsor’s Narrative and Critical History, vol. vii. It would be
as undesirable as it is unnecessary to supply, as could readily
be done, instances of gross cruelty and barbarity inflicted by
the Whigs upon the unfortunate loyalists “who remained at
home.” The Correspondence of Lord Cornwallis gives a most
painful picture of the condition of things in the South (Corr., i.
73), and the letters of Count Fersen, who cannot be suspected
of prejudice, reveal the hardly less savage condition of affairs
in the North. He says, for example, of Rhode Island (Letters, i.
40, 41):
“C’est un pays qui sera fort heureux s’il jouit d’une paix
longue, et si les deux partis qui le divisent à present ne lui font
subir le sort de la Pologne et de tant d’autres républiques. Ces
deux partes sont appelés les Whigs et les Torys. Le premier
est entièrement pour la liberté et l’independance; il est
composé de gens de la plus basse extraction qui ne possédent
point de biens; la plupart des habitants de la compagne en
sont. Les Torys sont pour les Anglais, ou, pour mieux dire,
pour la paix, sans trop se soucier d’être libres ou dépendants;
ce sont les gens d’une classe plus distinguée, les seuls qui
eussent des biens dans le pays. Lorsque les Whigs sont les
plus forts, ils pillent les autres tant qu’ils peuvent.”
162
Simcoe, Lt.-Col. J. G., A History of the Operations of a
Partisan Corps called the Queen’s Rangers, commanded by
Lt.-Col. J. G. Simcoe, during the war of the American
Revolution. New York: Bartlett and Welford, 1884, 8vo, pp.
328.
163
The Americans made several attempts to make use of the
Indians: Montgomery used them in his Canadian expedition;
they were in the New England army which laid siege to Boston;
in April, 1776, Washington wrote to Congress urging their
employment in the army, and reported on July 13th that,
without special authority, he had directed General Schuyler to
engage the Six Nations on the best terms he and his
colleagues could procure; and again, submitting the propriety
of engaging the Eastern Indians. John Adams thought “we
need not be so delicate as to refuse me assistance of Indians,
provided we cannot keep them neutral.” A treaty was
exchanged with the Eastern Indians on July 17, 1776, whereby
they agreed to furnish six hundred Indians for a regiment which
was to be officered by the whites. As a result of this, the
Massachusetts Council subsequently reported that seven
Penobscot Indians, all that could be procured, were enlisted in
October for one year; and in November Major Shaw reported
with a few Indians who had enlisted in the Continental service.
Winsor, Narr. and Crit. Hist., vol. vi. 656, 657. The following
brief entry in a diary will show that even among the patriot
forces savage customs sometimes found place: “On Monday
the 30th sent out a party for some dead Indians. Toward
morning found them, and skinned two of them from their hips
down for boot legs: one pair for the major, the other for myself.”
Proceedings N. J. Hist. Soc., ii. p. 31.
164
North American Review, lix. 264 (Sabine). “The opponents of
the Revolution were powerful in all the thirteen colonies; in
some of them they were nearly if not quite equal in number to
its friends the Whigs. On the departure of Hutchinson he was
addressed by upwards of two hundred merchants, lawyers and
other citizens of Boston, Salem and Marblehead. On arrival of
Gage, forty-eight from Salem presented their dutiful respects;
on his retirement he received the ‘Loyal address from
gentlemen and principal inhabitants of Boston’ to the number
of ninety-seven, and eighteen country gentlemen and official
personages who had taken refuge in Boston.” ...

* * * * *
“The division of parties in Connecticut, Rhode Island and
New Hampshire was much the same as in Massachusetts.
New York was the loyalists’ stronghold, and contained more of
them than any colony in America. While proof to sustain this
assertion can be adduced to almost any extent, we shall cite
but a single though conclusive fact; namely, that soon after the
close of the war the Assembly of that State passed a bill
prohibiting adherents of the crown from holding office, which
was objected to and returned by the Council of Revision, who,
among other reasons for their course, stated, that if it were
suffered to become a law, there would be difficulty, and in
some places an impossibility, of finding men of different
political sympathies, even to conduct the elections. In some of
the southern colonies, the loyalists were almost as numerous
as in New York. In the Carolinas it may be hard to determine
which party had the majority; and it will be found that there
were occasions when the royal generals obtained twelve or
fifteen hundred recruits among the inhabitants, merely by
issuing a proclamation or call upon them to stand by their
allegiance to “the best of sovereigns.... Few of the Carolinians
would enlist under the American banner; but after the
capitulation (of Charlestown) they flocked to the royal standard
by hundreds.” See also Sabine’s Loyalists, Introductory
Sketch; Ryerson, Loyalists of America, ii. 57, 124. For remarks
on the war, as a civil war, see Ramsay, Hist. U. S., ii. 467–9.
165
Sabine, i. 65.
166
A. W. Farmer, The Congress Canvassed, pp. 17–19, exhibits
the manner in which delegates to Congress were chosen in
New York. “The New York City committee (a self-appointed
body) applied to the supervisors in the several counties to call
the people together and to choose committees, which
committees were to meet in one grand committee; and this
grand committee of committees were to choose the delegates
for the county or to declare their approbation of the New York
delegates, and if any county did not meet and choose their
committee it was to be taken for granted that they acquiesced
in the New York choice.” Again as to delegates chosen by the
Assemblies: “The Assembly has no legal right to act by itself
and claim to represent the people in so doing. The people are
not bound by any act of their representatives till it hath
received the approbation of the other branches of the
legislature. Delegates so appointed are, at best, but delegates
of delegates, but representatives of representatives. When
therefore the delegates at Philadelphia, in the preamble to their
Bill of Rights, and in their letter to his Excellency General
Gage, stiled their body ‘a full and free representation of ... all
the Colonies from Nova Scotia to Georgia,’ they were guilty of
a piece of impudence which was never equalled since the
world began, and never will be exceeded while it shall
continue.” Again: “No provincial legislature (even if complete)
can give them such powers as were lately exercised at
Philadelphia. The legislative authority of the province cannot
extend further than the province extends. None of its acts are
binding one inch beyond its limits. How then can it give
authority to a few persons, to make rules and laws for the
whole continent?... Before such a mode of legislation can take
place, the constitution of our colonies must be subverted and
their present independency on one another must be
annihilated.”
The logic of the loyalist writers is unanswerable, and their
legal reasoning is usually correct and precise; the fallacy of
their position was that they were in face of a revolution.
Elements had been introduced into the struggle which, like the
presence of an infinite quantity in an equation, vitiated the
reasoning, however correct the process may have been. The
author argues, for example: “To talk of subjection to the King of
Great Britain, while we disclaim submission to the Parliament
of Great Britain, is idle and ridiculous. It is a distinction made
by the American Republicans to serve their own rebellious
purposes, a gilding with which they have enclosed the pill of
sedition, to entice the unwary colonists to swallow it the more
readily down. The King of Great Britain was placed on the
throne by virtue of an Act of Parliament: And he is king of
America, by virtue of being king of Great Britain. He is
therefore king of America by Act of Parliament. And if we
disclaim that authority which made him our king, we, in fact,
reject him from being our king, for we disclaim that authority by
which he is king at all.” It may be noticed that the fundamental
Whig doctrine of the supremacy of Parliament, which is here
so strongly urged, was never understood or appreciated by
those who called themselves Whigs in America.
167
Clinton-Cornwallis Correspondence, i. pp. 263, 265.
168
Clinton-Cornwallis Correspondence, ii. pp. 308, 309.
169
Jones, Thomas, History of New York, i. 362–3, 172–176.
170
Christian Examiner, viii. pp. 127, 128 (Dabney). Curwen,
Journal, 475, 479.
171
Sabine, North American Review, lix. pp. 287, 288. Loyalists, i.
71–81. Ryerson, Loyalists of America, ii. 130, 136.
172
No. Am. Rev., lix. p. 289.
173
The Journal and Letters of the late Samuel Curwen, New York
and Boston, 1842, p. 147.
174
Parliamentary History, vol. xxiii. 411, 412, 430, 481. The
following extracts may be added to those given in the text; Mr.
Burke said: “Better to have left the whole to future negotiation,
and to have been totally silent upon the subject in the treaty,
than to have consented to have set our hands to a gross libel
on the national character, and in our flagitious article plunged
the dagger into the hearts of the loyalists, and manifested our
own impotency, ingratitude and disgrace” (p. 468). In the same
debate Mr. Lee said: “Europe, Asia, Africa and America beheld
the dismembership and diminution of the British Empire. But
this, alarming and calamitous as it was, was nothing when put
in competition with another of the crimes of the present peace,
the cession of men into the hands of their enemies, and
delivering over to confiscation, tyranny, resentment and
oppression the unhappy men who trusted to our fair promises
and deceitful words. This was the great ground of his
objection: and he called it a disgraceful, wicked and
treacherous peace; inadequate to its object, and such as no
man could vote to be honorable without delivering his
character over to damnation for ever” (p. 492).
175
Ryerson, ii. 64. Curwen’s Journal, 367. Jones, History of N. Y.,
ii. The bitterness of the mortification, and resentment at the
treatment they had received from the hands of their friends, is
well exhibited in Judge Jones’s remarkable work, which,
however trustworthy or the reverse it may be in other respects,
may be followed implicitly as an exhibition of loyalist feeling
towards the mother country.
176
Jones, ii. 645–654. Wilmot, Historical View of the Commission
for Enquiry into the Losses, etc., London, 1815. Ryerson, ii.
159–182. Diary and Letters of Thomas Hutchinson, ii. 435–
437. Sabine, i. 86–90. In March, 1784, the number of persons
who had preferred their petitions was 2,063, and the alleged
losses £7,046,278, besides outstanding debts in America
amounting to £2,354,135. “In 1788 Mr. Pitt submitted a plan for
classifying the claimants, and of classifying and apportioning
the nature and amount of consolation to be allotted to each;
and to those whose losses had been caused principally by the
deprivation of official or professional incomes, he proposed a
system of pensions. By the 5th of April, this year (1790), the
Commissioners in England had heard and determined 1,680
claims, and had liquidated the same at the sum of £1,887,548.
It appeared, finally, that the number of applicants from
England, and from the Canadian provinces, attained to the
aggregate of 5,072, of which 954 either withdrew their
applications or failed to press them, and the sum of the losses
is stated to have been £8,026,045. Another return is made out
by Mr. J. E. Wilmot, one of the Commissioners, wherein the
amount of the claim is given as £10,358,413, and the amount
of the claims allowed at £3,033,091. The subject was again
raised in Parliament in 1821, but though there was much
sympathy expressed for the sufferings of those who had
trusted to their country to recompense their fidelity, the
sympathy exhausted itself in words.” See also Lecky, England
in the Eighteenth Century, iv. 268. Curwen, 367, 368.
177
Ryerson, ii. 127. No. Am. Rev., lix. 279. Hawkins, Missions of
the Church of England, 249. The Frontier Missionary, or Life of
the Rev. Jacob Bailey, by W. S. Bartlett, New York, 1853
(Collections of the Protestant Episcopal Historical Society, vol.
ii.). This work gives a pathetic account of the hardships and
privations undergone by the exiles in Nova Scotia, as well as a
graphic picture of the methods used by the town committees in
New England with those who adhered to the cause of the king.
178
Hawkins, Missions, 371–3. Ryerson, ii. 206. Mass. Hist. Soc.
Proceedings, Oct., 1886, p. 95. For the treatment of the
loyalists in the United States after the treaty of peace, see
especially Jones, Hist. New York, vol. ii. Roberts, Hist. of New
York, ii. 449 ff. Lecky (Hist. England in the Eighteenth Century,
iv. 267) remarks rather sharply: “The loyalists to a great extent
sprung from and represented the old gentry of the country. The
prospect of seizing their property had been one great motive
which induced many to enter the war. The owners of the
confiscated property now grasped the helm. New men
exercised the social influence of the old families, and they
naturally dreaded the restoration of those whom they had
displaced.”
179
Vide supra, Note 11.
180
No. Am. Rev., lix. 262 (Sabine). Lecky’s tribute to the loyalists
may be added: “There were brave and honest men in America
who were proud of the great and free empire to which they
belonged, who had no desire to shrink from the burden of
maintaining it, who remembered with gratitude the English
blood that had been shed around Quebec and Montreal, and
who, with nothing to hope for from the crown, were prepared to
face the most brutal mob violence and the invectives of a
scurrilous press, to risk their fortunes, their reputations, and
sometimes even their lives, in order to avert civil war and
ultimate separation. Most of them ended their days in poverty
and exile, and as the supporters of a beaten cause history has
paid but a scanty tribute to their memory, but they comprised
some of the best and ablest men America has ever produced,
and they were contending for an ideal which was at least as
worthy as that for which Washington fought. The maintenance
of one free, industrial and pacific empire, comprising the whole
English race, may have been a dream, but it was at least a
noble one.” History of England in the Eighteenth Century, iii.
418. For historical notices of the loyalists in Canada, the
following are also useful: Settlement of Upper Canada (1872),
by William Canniff; Toronto of Old (1873), by Dr. H. Scadding;
Centennial of the Settlement of Upper Canada by the United
Empire Loyalists, 1784–1884; The Celebrations at
Adolphustown, Toronto, and Niagara, Toronto, 1885.

THE END.
Transcriber’s Notes
Punctuation, hyphenation, and spelling were made
consistent when a predominant preference was found in the
original book; otherwise they were not changed.
Simple typographical errors were corrected; unbalanced
quotation marks were remedied when the change was
obvious, and otherwise left unbalanced.
The last footnote of the book (180) on page 210 had no
anchor. Transcriber added one at the end of the last
paragraph on page 198.

You might also like