You are on page 1of 67

Programming in Ada 2012 with a

Preview of Ada 2022 2nd Edition John


Barnes
Visit to download the full and correct content document:
https://ebookmass.com/product/programming-in-ada-2012-with-a-preview-of-ada-202
2-2nd-edition-john-barnes/
Programming
in Ada 2012
with a Preview of
Ada 2022

Published online by Cambridge University Press


Published online by Cambridge University Press
Programming
in Ada 2012
with a Preview of
Ada 2022
JOHN BARNES

Published online by Cambridge University Press


University Printing House, Cambridge CB2 8BS, United Kingdom

One Liberty Plaza, 20th Floor, New York, NY 10006, USA


477 Williamstown Road, Port Melbourne, VIC 3207, Australia

314–321, 3rd Floor, Plot 3, Splendor Forum, Jasola District Centre, New Delhi – 110025, India
103 Penang Road, #05–06/07, Visioncrest Commercial, Singapore 238467

Cambridge University Press is part of the University of Cambridge.

It furthers the University’s mission by disseminating knowledge in the pursuit of


education, learning, and research at the highest international levels of excellence.

www.cambridge.org
Information on this title: www.cambridge.org/9781009181341
DOI: 10.1017/9781009181358

© John Barnes 2014, 2022

This publication is in copyright. Subject to statutory exception


and to the provisions of relevant collective licensing agreements,
no reproduction of any part may take place without the written
permission of Cambridge University Press.
First published 2014
Reprinted with corrections and additions 2021
Second edition 2022
A catalogue record for this publication is available from the British Library.

ISBN 978-1-009-18134-1 Paperback

Additional resources for this publication at www.cambridge.org/barnes12-22

Cambridge University Press has no responsibility for the persistence or accuracy of


URLs for external or third-party internet websites referred to in this publication
and does not guarantee that any content on such websites is, or will remain,
accurate or appropriate.

Published online by Cambridge University Press


To Barbara

Published online by Cambridge University Press


Published online by Cambridge University Press
Contents

Foreword xv
Preface xvii

Part 1 An Overview 1
1 Introduction 3
1.1 Standard development 3
1.2 Software engineering 4
1.3 Evolution and abstraction 6
1.4 Structure and objectives of this book 8
1.5 References 10
2 Simple Concepts 11
2.1 Key goals 11
2.2 Overall structure 12
2.3 The scalar type model 17
2.4 Arrays and records 19
2.5 Access types 22
2.6 Errors and exceptions 23
2.7 Terminology 26
3 Abstraction 27
3.1 Packages and private types 27
3.2 Objects and inheritance 30
3.3 Classes and polymorphism 34
3.4 Genericity 40
3.5 Object oriented terminology 41
3.6 Tasking 43
4 Programs and Libraries 47
4.1 The hierarchical library 47
4.2 Input–output 49

vii

Published online by Cambridge University Press


viii Contents

4.3 Numeric library 52


4.4 Running a program 54
Program 1 Magic Moments 59

Part 2 Algorithmic Aspects 63


5 Lexical Style 65
5.1 Syntax notation 65
5.2 Lexical elements 66
5.3 Identifiers 67
5.4 Numbers 68
5.5 Comments 71
5.6 Pragmas and aspects 71
6 Scalar Types 73
6.1 Object declarations and assignments 73
6.2 Blocks and scopes 75
6.3 Types 77
6.4 Subtypes 79
6.5 Simple numeric types 81
6.6 Enumeration types 87
6.7 The type Boolean 90
6.8 Categories of types 93
6.9 Expression summary 95
7 Control Structures 101
7.1 If statements 101
7.2 Case statements 105
7.3 Loop statements 108
7.4 Goto statements and labels 114
7.5 Statement classification 111
8 Arrays and Records 117
8.1 Arrays 117
8.2 Array types 122
8.3 Array aggregates 127
8.4 Characters and strings 132
8.5 Arrays of arrays and slices 135
8.6 One-dimensional array operations 138
8.7 Records 143
9 Expression Structures 149
9.1 Membership tests 149
9.2 If expressions 151

Published online by Cambridge University Press


Contents ix

9.3 Case expressions 155


9.4 Quantified expressions 157
10 Subprograms 161
10.1 Functions 161
10.2 Operators 169
10.3 Procedures 171
10.4 Aliasing 177
10.5 Named and default parameters 179
10.6 Overloading 181
10.7 Declarations, scopes, and visibility 182
11 Access Types 189
11.1 Flexibility versus integrity 189
11.2 Access types and allocators 191
11.3 Null exclusion and constraints 198
11.4 Aliased objects 200
11.5 Accessibility 204
11.6 Access parameters 206
11.7 Anonymous access types 210
11.8 Access to subprograms 214
11.9 Storage pools 220
Program 2 Sylvan Sorter 223

Part 3 The Big Picture 227


12 Packages and Private Types 229
12.1 Packages 229
12.2 Private types 234
12.3 Primitive operations and derived types 241
12.4 Equality 247
12.5 Limited types 251
12.6 Resource management 257
13 Overall Structure 263
13.1 Library units 263
13.2 Subunits 266
13.3 Child library units 268
13.4 Private child units 272
13.5 Mutually dependent units 279
13.6 Scope, visibility, and accessibility 283
13.7 Renaming 287
13.8 Programs, partitions, and elaboration 292

Published online by Cambridge University Press


x Contents

Program 3 Rational Reckoner 297


14 Object Oriented Programming 301
14.1 Type extension 301
14.2 Polymorphism 307
14.3 Abstract types and interfaces 315
14.4 Primitive operations and tags 318
14.5 Views and redispatching 328
14.6 Private types and extensions 334
14.7 Controlled types 342
14.8 Multiple inheritance 347
14.9 Multiple implementations 353
15 Exceptions 361
15.1 Handling exceptions 361
15.2 Declaring and raising exceptions 364
15.3 Checking and exceptions 370
15.4 Exception occurrences 372
15.5 Exception pragmas and aspects 376
15.6 Scope of exceptions 381
16 Contracts 385
16.1 Aspect specifictions 385
16.2 Preconditions and postconditions 388
16.3 Type invariants 399
16.4 Subtype predicates 405
16.5 Messages 413
17 Numeric Types 417
17.1 Signed integer types 417
17.2 Modular types 423
17.3 Real types 425
17.4 Floating point types 427
17.5 Fixed point types 430
17.6 Decimal types 436
18 Parameterized Types 439
18.1 Discriminated record types 439
18.2 Default discriminants 443
18.3 Variant parts 449
18.4 Discriminants and derived types 453
18.5 Access types and discriminants 456
18.6 Private types and discriminants 463
18.7 Access discriminants 465

Published online by Cambridge University Press


Contents xi

19 Generics 469
19.1 Declarations and instantiations 469
19.2 Type parameters 475
19.3 Subprogram parameters 485
19.4 Package parameters 492
19.5 Generic library units 498
20 Tasking 501
20.1 Parallelism 501
20.2 The rendezvous 503
20.3 Timing and scheduling 508
20.4 Protected objects 513
20.5 Simple select statements 521
20.6 Timed and conditional calls 524
20.7 Concurrent types and activation 527
20.8 Termination, exceptions, and ATC 534
20.9 Signalling and scheduling 540
20.10 Summary of structure 546
21 Object Oriented Techniques 551
21.1 Extension and composition 551
21.2 Using interfaces 554
21.3 Mixin inheritance 560
21.4 Linked structures 562
21.5 Iterators 565
21.6 Generalized iteration 570
21.7 Object factories 577
21.8 Controlling abstraction 581
22 Tasking Techniques 587
22.1 Dynamic tasks 587
22.2 Multiprocessors 590
22.3 Synchronized interfaces 598
22.4 Discriminants 609
22.5 Task termination 614
22.6 Clocks and timers 617
22.7 The Ravenscar profile 626
Program 4 Super Sieve 627

Part 4 Completing the Story 631


23 Predefined Library 633
23.1 The package Standard 633
23.2 The package Ada 637

Published online by Cambridge University Press


xii Contents

23.3 Characters and strings 640


23.4 Numerics 659
23.5 Input and output 663
23.6 Text input–output 669
23.7 Streams 678
23.8 Environment commands 684
Program 5 Wild Words 695
24 Container Library 699
24.1 Organization of library 699
24.2 Doubly linked lists 701
24.3 Vectors 709
24.4 Maps 713
24.5 Sets 725
24.6 Trees 737
24.7 Holder 747
24.8 Queues 749
24.9 Bounded containers 757
24.10 Indefinite containers 761
24.11 Sorting 767
24.12 Summary table 769
25 Interfacing 781
25.1 Representations 781
25.2 Unchecked programming 785
25.3 The package System 788
25.4 Storage pools and subpools 790
25.5 Other languages 797
Program 6 Playing Pools 803
26 The Specialized Annexes 807
26.1 Systems Programming 807
26.2 Real-Time Systems 809
26.3 Distributed Systems 813
26.4 Information Systems 815
26.5 Numerics 815
26.6 High Integrity Systems 820
27 Finale 823
27.1 Names and expressions 823
27.2 Type equivalence 827
27.3 Overall program structure 830
27.4 Portability 834

Published online by Cambridge University Press


Contents xiii

27.5 Penultimate thoughts 836


27.6 SPARK 839

Appendices 851
A1 Reserved Words, etc. 851
A1.1 Reserved words 851
A1.2 Predefined attributes 852
A1.3 Predefined aspects 859
A1.4 Predefined pragmas 862
A1.5 Predefined restrictions 864
A2 Glossary 867
A3 Syntax 873
A3.1 Syntax rules 873
A3.2 Syntax index 891
A4 Introducing Ada 2022 901
A5.6a Generalized literals 902
A7.3a Iteration filters 902
A8.8 General aggregates 903
A9.5 Declare expressions 904
A9.6 Reduction expressions 905
A13.7a Renaming objects and values 906
A15.5a Aspect No_Return 907
A16.2a Default initial conditions 907
A16.2b Contracts and access types 908
A16.6 Global state 908
A19.2a Default generic parameters 912
A20.2a Entries, aspects, and synchronization 913
A21.6a Iterator interfaces 914
A21.6b Procedural iterators 915
A22.7a Profiles 917
A22.8 Parallel blocks and loops 917
A22.9 Conflict checking 919
A23.4a Big numbers 920
A23.4b Random numbers 927
A23.6a Images 927
A23.6b Text buffers 928
A24a Containers 931
A24.2a Doubly linked lists 931
A24.3a Vectors 939
A24.4a Maps 941
A24.5a Sets 942
A24.6a Trees 943

Published online by Cambridge University Press


xiv Contents

A24.7a Holder 944


A25.1a Size and representation attributes 945
A26.1a Atomic operations 945
A27.1a Staticness 946

Answers to Exercises 947


Bibliography 951
Index 953

Published online by Cambridge University Press


Foreword

T his is being written shortly after the successful launch of the James Webb Space
Telescope, a demonstration of what can be achieved if enough care is taken with
the software engineering.
It is also on the cusp between 2021 and 2022, a time to both look backwards and
to look forward. It is a similar matter with Ada 2022. On one hand, it looks back,
filling in gaps in what should, with the benefit of hindsight, have already been in
earlier editions of Ada. On the other hand, it looks forward to a world where many-
core processors are ubiquitous and need to be made use of efficiently.
The Ada programming language continues to evolve in order to better support
the development of software applications with high requirements for reliability and
system integrity. The 4th major revision of the language, Ada 2022, includes
improvements in many different areas, but with particular focus on a few topics:

• allowing software developers to easily and safely take advantage of the parallel
execution capabilities of multi-core and multi-threaded architectures;
• allowing developers to more precisely express their intent regarding a
program’s structure and logic via improved contracts and other forms of
assertions;
• providing improved support for containers;
• providing “creature comforts” to ease the use of common programming idioms.

The introduction of parallel loops and parallel block statements allows users to
express the possibility of parallel execution of constructs that also have well-
defined sequential semantics. The Global and Nonblocking aspects can be used to
enable static detection of unsafe concurrent access to variables.
Contracts are improved along two different axes: contracts are supported in
more contexts (e.g., the Default_Initial_Condition aspect and support for
precondition/postcondition specifications for access-to-subprogram types and for
generic formal subprograms), and more expressive forms of expressions are defined
in order to make it possible to write more precise contracts (e.g., declare
expressions, reduction expressions, delta aggregates, and calls to static functions).
There is a sometimes-unappreciated point about some of these expression forms that
may seem like just syntactic sugar (another example is Ada 2012’s quantified
expressions). It is true that the same value could be computed in a function body

xv

https://doi.org/10.1017/9781009181358.001 Published online by Cambridge University Press


xvi Foreword

without too much trouble, but then what would the postcondition be for this
function? How would the declaration of the function describe its result? So these
new forms do enable more expressive contracts.
Support is added for iterating over containers, and for constructing container
values using aggregates. The mechanisms used to accomplish this can also be used
in user-defined container implementations; the implementation-defined containers
have no special “magic” that is unavailable to users who want to “roll their own”.
Support is also provided for literals of private types, for indexing operations on a
private type, for implicit dereferencing of certain non-access types; all of these are
intended to make it easier to hide the implementation of a private type without
taking useful functionality away from clients. And the private type in question may,
of course, be a container type.
“Creature comforts” include the introduction of some features that have long
been available in other programming languages. A name ("@") is defined for the
target of an assignment statement, as in:

Function_Call.Some_Long_Name(Some_Index_Expression) : = @ + 1;

The Image attribute is now available for almost all types and objects, not just
for scalars; support for (in effect) user-specified Image functions is provided.
Restrictions on aggregates are relaxed (index values can now be used in array
aggregate component expressions); a discriminant value in an aggregate can be non-
static in more cases. Predefined support for big numbers (integer and real) is added.
Internationalization support is improved via the various new Wide_File_Names and
Wide_Wide_File_Names packages.
And there are many, many other improvements to the language as well. The
Jorvik profile, the System.Atomic_Operations package, the Object_Size attribute,
iterator filters, and lots of other stuff.
And who better to guide a user through all of this material than John Barnes?
John has been involved in Ada programming language design efforts since shortly
after the birth of Ada Lovelace (or so it seems). He combines his detailed
knowledge of the subject with a special talent for exposition. He has an unusual
ability to anticipate, and correct for, the ways that a reader might be confused by
whatever corner of the language he is describing. His choices of examples are
invariably both enlightening and entertaining. His writing combines technical
correctness with accessibility and humor.
For folks who want to write software that works correctly (admittedly, a small
audience), there is value in learning about Ada and, in particular, about Ada 2022.
And for anyone who wants to learn about Ada, there is both value and fun in
learning about it from John’s fine book.

Enjoy!
Steve Baird & Jeff Cousins,
Current and Past Chairs of the
ISO/IEC JTC1/SC22/WG9
Ada Rapporteur Group (ARG)

https://doi.org/10.1017/9781009181358.001 Published online by Cambridge University Press


Preface

elcome to this updated version of Programming in Ada 2012 which describes


W Ada 2012 as revised by the Corrigendum approved and published by ISO in
2016 and also includes an extensive appendix entitled Introducing Ada 2022.
The original language, devised in the 1980s, is known as Ada 83 and was
followed by Ada 95, Ada 2005, and then Ada 2012. We are now on the verge of Ada
2022 which as I write is currently being processed by ISO and is almost certain to
be approved in 2022. But as life with a virus shows, the future is never certain!
However, although Ada 2022 is now imminent, it is likely that Ada 2012 will
continue in use in its own right for some time. Accordingly, it seems appropriate to
present both Ada 2012 and Ada 2022 so that the book can serve the needs of those
continuing to use Ada 2012 and also those moving to Ada 2022 in the near future.
The book has therefore been structured so that the main chapters describe the
2016 updated version of Ada 2012 in detail. The book concludes with a major
appendix describing the key new features of Ada 2022.
Ada has gained a reputation as being the language of choice when software
needs to be correct. And as software pervades into more areas of society so that ever
more software is safety critical or security critical, it is clear that the future for Ada
is bright. One observes, for example, the growth in use of SPARK, the Ada based
high integrity language widely used in areas such as avionics and signalling.
Ada 83 was a relatively simple but highly reliable language with emphasis on
abstraction and information hiding. It was also notable for being perhaps the first
practical language to include multitasking within the language itself.
Ada 95 added extra flexibility in the form of the full dynamic features of Object
Oriented Programming (OOP) and in fact was the first such language to become an
ISO standard. Ada 95 also made important structural enhancements to visibility
control by the addition of child units and greatly improved multitasking by the
addition of protected types.
Ada 2005 then added more flexibility in the OOP area by the addition of
multiple inheritance via interfaces and it also added more facilities in the real-time
area concerning scheduling algorithms, timing and so on. It also added further
facilities to the standard library such as the introduction of a container library.
Ada 2012 made further very important enhancements. Perhaps the most
important was the addition of features for contracts such as pre- and postconditions
and type invariants. These in turn showed the need for more flexible expressions
and so conditional expressions, case expressions, and quantified expressions were

xvii

https://doi.org/10.1017/9781009181358.002 Published online by Cambridge University Press


xviii Preface

also added. Tasking facilities were enhanced to recognize multicore architectures.


The container library was also enhanced to include multiway trees and task-safe
queues. Bounded forms of all containers which are important for high integrity
systems where dynamic storage management is often not permitted were also
added.
Ada 2022 makes important improvements in two key areas: reliability and
efficiency. Reliability is improved by contracts which are strengthened by the
addition of annotations describing the manipulation of global state. The form of
contracts as pre- and postconditions which take the form of expressions has
stimulated the enhancement of the power of expressions. So Ada is being nudged in
the direction of expression/functional languages (but not too much). The other area
of concern is efficiency and this is addressed by the inclusion of lightweight parallel
features to enable the straightforward use of multiprocessors. Both reliability and
efficiency are addressed in the container library by the concept of stable state which
enables many common operations to be performed more efficiently but still with
full reliability.
The main body of the book comprises 27 chapters grouped into four parts as
follows

• Chapters 1 to 4 provide an overview which should give the reader an


understanding of the overall scope of the language as well as the ability to run
significant programs as examples – this is particularly for newcomers to Ada.
• Chapters 5 to 11 cover the small-scale aspects such as the lexical details, scalar,
array and simple record types, control and expression structures, subprograms
and access types.
• Chapters 12 to 22 discuss the large-scale aspects including packages and private
types, contracts, separate compilation, abstraction, OOP and tasking as well as
exceptions and the details of numerics.
• Chapters 23 to 27 complete the story by discussing the predefined library,
interfacing to the outside world and the specialized annexes; there is then a
finale concluding with some ruminations over correctness and a brief
introduction to SPARK.

The finale includes, as do its predecessors, a fantasy customer in a shop trying


to buy reusable software components and whose dream now seems as far away or
indeed as near at hand as it did many years ago when I first toiled at this book. The
discussion continues to take a galactic view of life and perhaps echoes the cool
cover of the book which depicts NGC 7027, the Jewel Bug nebula. Maybe one can
view this as the new Ada 2022 bursting from the domain of Ada 2012!
There are various appendices. The first summarises the reserved words, aspects
attributes, pragmas, and restrictions. The second is a glossary. The third gives the
full syntax of the 2016 version.
The fourth appendix is an overview of the important new features in Ada 2022.
It is arranged into subsections that match those of the body of the book describing
the 2016 version. Thus appendix Section A19.2a contains material relating to
Section 19.2 of the main body whereas Section A9.5 is a completely new
subsection for Chapter 9.

https://doi.org/10.1017/9781009181358.002 Published online by Cambridge University Press


Preface xix

In order to avoid the book becoming unwieldy, the full details of the syntax for
Ada 2022 and an updated table summarising the containers in Ada 2022 are
provided on the website. The answers to all exercises are also on the website but
those for the introductory Part 1 are also included in the book for the convenience
of readers encountering Ada for the first time. More details of the website will be
found below.
Whenever a new standard appears and is put into use, it is almost inevitable that
various imperfections are soon discovered. Ada 2012 was no exception and a
number of corrections and improvements were deemed to be necessary. These
alterations were processed in the usual manner by the Ada Rapporteur Group and
resulted in a Corrigendum which was approved and published by ISO in February
2016. The body of this version of Programming in Ada 2012 accordingly covers this
updated 2016 standard. I have also taken the opportunity to convert the uses of
pragmas such as Pure and Preelaborate to aspect clauses in order to smooth the
transition to Ada 2022.
The revisions are described by Ada Issues (AIs) and a number of these are
mentioned in the Index. The early ones relate to the 2016 corrigendum but most
concern the evolution of Ada 2022.
And now I must thank all those who have helped with this new book both by
pointing out errors in the first edition and by reviewing the text of this new edition
and especially the Ada 2022 material. Many thanks therefore (in alphabetical order)
to Steve Baird, Janet Barnes, Ben Brosgol, Randy Brukardt, Jeff Cousins, Bob Duff,
Tama McGlinn, Pascal Pignard, and Tucker Taft. Their much valued comments
enabled me to improve the presentation and to eliminate a number of errors. I must
also give extra thanks to Randy Brukardt without whose eternal energy as editor of
the Ada standard, I would find writing about Ada a very difficult task indeed.
Finally, many thanks to my wife Barbara for help in typesetting and proof-
reading and to friends at Cambridge University Press for their continued guidance
and help.
John Barnes
Caversham, England
January 2022

Notes on the website


The website for this book is www.cambridge.org/barnes12-22. As well as the full
syntax for Ada 2022 and a table giving a summary of all container operations in Ada
2022, it contains the answers to all the exercises, some obscure or obsolete material
on exceptions, discriminants, and iterators which were in previous versions of the
book, additional material on the six sample programs in the body of the book and
some further programs illustrating new features in Ada 2022.
Each example in the book commences with some remarks about its purpose and
overall structure. This is followed by the text of the program and then some notes
on specific details. A desire to keep the program text short means that comments are
at a minimum. However, the corresponding source text on the website includes
much additional commentary. The website also includes further discussion and
explanation and suggestions for enhancement. In general the programs use only
those features of the language explained in detail by that point in the book.

https://doi.org/10.1017/9781009181358.002 Published online by Cambridge University Press


xx Preface

The first program, Magic Moments, illustrates type extension and dispatching.
It shows how the existence of common components and common operations enable
dispatching to compute various geometrical properties almost by magic.
The Sylvan Sorter is an exercise in access types and basic algorithmic
techniques including recursion.
The Rational Reckoner provides two examples of abstract data types – the
rational numbers themselves and the stack which is the basis of the calculator part
of the program.
The Super Sieve illustrates multitasking and communication between tasks both
directly through entry calls and indirectly through protected objects. For added
interest it is made generic so that more general primes than those from the familiar
domain of integers may be found. This provides the opportunity to use a
discriminated record type and a modular type to represent binary polynomials.
The program Wild Words is probably the hardest to follow because it is not
based on any particular example described in the preceding chapters. It illustrates
many of the facilities of the character and string handling packages as well as the
generation of random numbers.
The final program from the book, Playing Pools, shows how users might write
their own storage allocation package for the control of storage pools. The example
shown enables the user to monitor the state of the pool and it is exercised by running
the familiar Tower of Hanoi program which moves a tower of discs between three
poles. Variety is provided by implementing the stack structures representing the
three poles (and defined by an interface) in two different ways and dispatching to
the particular implementation. The website includes an extended version which uses
three different ways.
The website also includes a number of sample programs illustrating new
features in Ada 2022. One program addresses encryption and uses the RSA
algorithm mentioned in Section A23.4a.
Information on many aspects of Ada such as vendors, standards, books and so
on can be obtained from the websites listed in the Bibliography.

https://doi.org/10.1017/9781009181358.002 Published online by Cambridge University Press


Part 1

An Overview

Chapter 1 Introduction 3
Chapter 2 Simple Concepts 11
Chapter 3 Abstraction 27
Chapter 4 Programs and Libraries 47
Program 1 Magic Moments 59

T
his first part covers the background to the Ada language and an
overview of most of its features. Enough material is presented
here to enable a programmer to write complete simple
programs.
Chapter 1 contains a short historical account of the origins and
development of various versions of Ada from Ada 83 through Ada 95
and Ada 2005 and leading to Ada 2012 and Ada 2022 which are the
topics of this book. There is also a general discussion of how the
evolution of abstraction has been an important key to the development
of programming languages in general.
Broadly speaking, the other three chapters in this part provide an
overview of the material in the corresponding other parts of the book.
Thus Chapter 2 describes the simple concepts familiar from languages
such as C and Pascal and which form the subject of the seven chapters
which comprise Part 2. Similarly Chapter 3 covers the important topic
of abstraction which is the main theme of Part 3. And then Chapter 4
rounds off the overview by showing how a complete program is put
together and corresponds to Part 4 which covers material such as the
predefined library.

https://doi.org/10.1017/9781009181358.003 Published online by Cambridge University Press


Chapter 3 includes a discussion of the popular topic of object
oriented programming and illustrates the key concepts of classes as
groups of related types, of type extension and inheritance as well as
static polymorphism (genericity) and dynamic polymorphism leading
to dynamic binding. It also includes a brief comparison between the
terminology used by Ada and that used by some other languages. This
chapter concludes with an introduction to tasking which is a very
important aspect of Ada and is a topic not addressed by most
programming languages at all.
This part concludes with the first of a number of complete programs
designed to give the reader a better understanding of the way the
various components of the language fit together. This particular
program illustrates a number of aspects of type extension and
polymorphism.
Those not familiar with Ada will find that this part will give them
a fair idea of Ada’s capabilities and lays the foundation for
understanding the details presented in the remainder of the book.

https://doi.org/10.1017/9781009181358.003 Published online by Cambridge University Press


1 Introduction

1.1 Standard development 1.4 Structure and objectives


1.2 Software engineering of this book
1.3 Evolution and abstraction 1.5 References

A da is a comprehensive high level programming language especially suited for


the professional development of large or critical programs for which
correctness and robustness are major considerations. In this introductory chapter we
briefly trace the development of Ada 2012 and then Ada 2022 (which is a draft
standard at the time of writing), the place of Ada in the overall language scene and
the general structure of the remainder of this book.

1.1 Standard development

A da 2012 (and the nascent Ada 2022) are direct descendants of Ada 83 which
was originally sponsored by the US Department of Defense for use in the
embedded system application area. (An embedded system is one in which the
computer is an integral part of a larger system such as a chemical plant, missile, or
dishwasher.)
The story of Ada goes back to about 1974 when the United States Department
of Defense realized that it was spending far too much on software, especially in the
embedded systems area. To cut a long story short the DoD sponsored the new
language through a number of phases of definition of requirements, competitive and
parallel development and evaluation which culminated in the issue of the ANSI
standard for Ada in 19831. The team that developed Ada was based at CII
Honeywell Bull in France under the leadership of Jean D Ichbiah.
The language was named after Augusta Ada Byron, Countess of Lovelace
(1815–52). Ada, the daughter of the poet Lord Byron, was the assistant and patron
of Charles Babbage and worked on his mechanical analytical engine. In a very real
sense she was therefore the world’s first programmer. Note that the 1983 standard
was published on Ada’s birthday (December 12) and the standard number 1815
happens to be the year of her birth!

https://doi.org/10.1017/9781009181358.004 Published online by Cambridge University Press


4 Introduction

Ada 83 became ISO standard 8652 in 1987 and, following normal ISO practice,
work leading to a revised standard commenced in 1988. The DoD, as the agent of
ANSI, the original proposers of the standard to ISO, established the Ada project in
1988 under the management of Christine M Anderson. The revised language design
was contracted to Intermetrics Inc. under the technical leadership of S Tucker Taft.
The revised ISO standard was published in February 1995 and so became Ada 952.
The maintenance of the language is performed by the Ada Rapporteur Group
(ARG) of ISO/IEC committee SC22/WG9. The ARG under the leadership of Erhard
Plödereder identified the need for some corrections and these were published as a
Corrigendum on 1 June 20013.
Experience with Ada 95 and other modern languages such as Java indicated that
further improvements would be very useful. The changes needed were not so large
as the step from Ada 83 to Ada 95 and so an Amendment was deemed appropriate
rather than a Revised standard. The ARG then developed the Amended language
known as Ada 2005 under the leadership of Pascal Leroy4.
Further experience with Ada 2005 showed that additions especially in the area
of contracts and multiprocessor support would be appropriate. It was decided that
this time a consolidated Edition should be produced. This was accordingly done
under the leadership of Ed Schonberg with the editor being Randy Brukardt and
resulted in the version known as Ada 2012 which became an ISO standard towards
the end of 20125. Maintenance then continued under the leadership of Jeff Cousins.
A number of corrections were made and resulted in the Corrigendum 1 version of
Ada 2012 published in 20166 and which is the subject of the main body of this book.
It was clear that further development was required in order to take full
advantage of the contract features and multiprocessor support. This progressed
under the leadership of Steve Baird and resulted in the draft ISO standard for Ada
2022 which is currently being processed. The main features of Ada 2022 are
described in Appendix 4.

1.2 Software engineering

I t should not be thought that Ada is just another programming language. Ada is
about Software Engineering, and by analogy with other branches of engineering
it can be seen that there are two main problems with the development of software:
the need to reuse software components as much as possible and the need to establish
disciplined ways of working.
As a language, Ada largely solves the problem of writing reusable software
components – or at least through its excellent ability to prescribe interfaces, it
provides an enabling technology in which reusable software can be written.
The establishment of a disciplined way of working seems to be a Holy Grail
which continues to be sought. One of the problems is that development
environments change so rapidly that the stability necessary to establish discipline
can be elusive.
But Ada is stable and encourages a style of programming which is conducive to
disciplined thought. Experience with Ada shows that a well designed language can
reduce the cost of both the initial development of software and its later
maintenance.

https://doi.org/10.1017/9781009181358.004 Published online by Cambridge University Press


1.2 Software engineering 5

The main reason for this is simply reliability. The strong typing and related
features ensure that programs contain few surprises; most errors are detected at
compile time and of those that remain many are detected by run-time constraints.
Moreover, the compile-time checking extends across compilation unit boundaries.
This aspect of Ada considerably reduces the costs and risks of program
development compared for example with C and its derivatives such as C++.
Moreover, an Ada compilation system includes the facilities found in separate tools
such as ‘lint’ and ‘make’ for C. Even if Ada is seen as just another programming
language, it reaches parts of the software development process that other languages
do not reach.
Ada 95 added extra flexibility to the inherent reliability of Ada 83. That is, it
kept the Software Engineering but allowed more flexibility. The features of Ada 95
which contributed to this more flexible feel are the extended or tagged types, the
hierarchical library facility and the greater ability to manipulate pointers or
references. Another innovation in Ada 95 was the introduction of protected types to
the tasking model.
As a consequence, Ada 95 incorporated the benefits of object oriented
languages without incurring the pervasive overheads of languages such as Smalltalk
or the insecurity brought by the weak C foundation in the case of C++. Ada 95
remained a very strongly typed language but provided the benefits of the object
oriented paradigm.
Ada 2005 added yet further improvements to the object model by adding
interfaces in the style of Java and providing constructor functions and also
extending the object model to incorporate tasking. Experience has shown that a
standard library is important and accordingly Ada 2005 had a much larger library
including predefined facilities for containers.
Ada has long been renowned as the flagship language for multitasking
applications. (Multitasking is often known as multithreading.) This position was
strengthened by the addition of further standard paradigms for scheduling and
timing and the incorporation of the Ravenscar profile into Ada 2005. The Ravenscar
profile enables the development of real-time programs with predictable behaviour.
Further improvements which resulted in Ada 2012 were in three main areas.
First there was the introduction of material for ‘programming by contract’ such as
pre- and postconditions somewhat on the lines of those found in Eiffel. There were
also additions to the tasking model including facilities for mapping tasks onto
multiprocessors. Other important extensions were additional facilities in the
container library enabling further structures (such as trees and queues) to be
addressed; other improvements also simplified many operations on the existing
container structures.
Ada 2022 builds on the experience with Ada 2012 in a number of areas. The use
of the contract model based on pre- and postconditions showed that their use would
be simplified and encouraged by the addition of more expression features. However,
although Ada 2022 has features enabling objects to be declared within expressions,
Ada is not moving towards being an expression language of the style historically
introduced by LISP with the attendant difficulties of legibility. Other proof related
features such as the ability to describe the effect of a subprogram on the overall
global state are also added. Major improvements are made to the container library
enabling greater efficiency of operation whilst retaining security. And lightweight

https://doi.org/10.1017/9781009181358.004 Published online by Cambridge University Press


6 Introduction

tasking is added to aid the simpler use of multiple processors. The key features of
Ada 2022 are described in Appendix 4.
Two kinds of application stand out where Ada is particularly relevant. The very
large and the very critical.
Very large applications, which inevitably have a long lifetime, require the
cooperative effort of large teams. The information hiding properties of Ada and
especially the way in which integrity is maintained across compilation unit
boundaries are invaluable in enabling such developments to progress smoothly.
Furthermore, if and when the requirements change and the program has to be
modified, the structure and especially the readability of Ada enable rapid
understanding of the original program even if it is modified by a different team.
Very critical applications are those that just have to be correct otherwise people
or the environment get damaged. Obvious examples occur in avionics, railway
signalling, process control, and medical applications. Such programs may not be
large but have to be very well understood and often mathematically proven to be
correct. The full flexibility of Ada is not appropriate in this case but the intrinsic
reliability of the strongly typed kernel of the language is exactly what is required.
Indeed many certification agencies dictate the properties of acceptable languages
and whereas they do not always explicitly demand a subset of Ada, nevertheless the
properties are not provided by any other practically available language. The SPARK
language which is based around a kernel subset of Ada illustrates how special tools
can provide extra support for developing high integrity systems. A SPARK program
includes additional information regarding data flow, state, and proof. In the original
versions of SPARK this was done in the form of Ada comments. However, in later
versions of SPARK, information is presented using features of Ada including pre-
and postconditions and additional assertions. This information is processed by the
SPARK tools and can be used to show that a program meets certain criteria such as
not raising any predefined exceptions. Much progress has been made in the area of
proof in recent years. A brief introduction to SPARK will be found in Chapter 27.

1.3 Evolution and abstraction


he evolution of programming languages has apparently occurred in a rather ad
T hoc fashion but with hindsight it is now possible to see a number of major
advances. Each advance seems to be associated with the introduction of a level of
abstraction which removes unnecessary and harmful detail from the program.
The first advance occurred in the early 1950s with high level languages such as
Fortran and Autocode which introduced ‘expression abstraction’. It thus became
possible to write statements such as

X = A + B(I)

so that the use of the machine registers to evaluate the expression was completely
hidden from the programmer. In these early languages the expression abstraction
was not perfect since there were somewhat arbitrary constraints on the complexity
of expressions; subscripts had to take a particularly simple form for instance. Later
languages such as Algol 60 removed such constraints and completed the
abstraction.

https://doi.org/10.1017/9781009181358.004 Published online by Cambridge University Press


1.3 Evolution and abstraction 7

The second advance concerned ‘control abstraction’. The prime example was
Algol 60 which took a remarkable step forward; no language since then has made
such an impact on later developments. The point about control abstraction is that the
flow of control is structured and individual control points do not have to be named
or numbered. Thus we write

if X = Y then P := Q else A := B

and the compiler generates the gotos and labels which would have to be explicitly
used in early versions of languages such as Fortran. The imperfection of early
expression abstraction was repeated with control abstraction. In this case the
obvious flaw was the horrid Algol 60 switch which has now been replaced by the
case statement of later languages.
The third advance was ‘data abstraction’. This means separating the details of
the representation of data from the abstract operations defined upon the data.
Older languages take a very simple view of data types. In all cases the data is
directly described in numerical terms. Thus if the data to be manipulated is not
really numerical (it could be traffic light colours) then some mapping of the abstract
type must be made by the programmer into a numerical type (usually integer). This
mapping is purely in the mind of the programmer and does not appear in the written
program except perhaps as a comment.
Pascal introduced a certain amount of data abstraction as instanced by the
enumeration type. Enumeration types allow us to talk about the traffic light colours
in their own terms without our having to know how they are represented in the
computer. Moreover, they prevent us from making an important class of
programming errors – accidentally mixing traffic lights with other abstract types
such as the names of fish. When all such types are described in the program as
numerical types, such errors can occur.
Another form of data abstraction concerns visibility. It has long been
recognized that the traditional block structure of Algol and Pascal is not adequate.
For example, it is not possible in Pascal to write two procedures to operate on some
common data and make the procedures accessible without also making the data
directly accessible. Many languages have provided control of visibility through
separate compilation; this technique is adequate for medium-sized systems, but
since the separate compilation facility usually depends upon some external system,
total control of visibility is not gained. The module of Modula is an example of an
appropriate construction.
Ada was probably the first practical language to bring together these various
forms of data abstraction.
Another language which made an important contribution to the development of
data abstraction is Simula 67 with its concept of class. This leads us into the
paradigm now known as object oriented programming. There seems to be no precise
definition of OOP, but its essence is a flexible form of data abstraction providing
the ability to define new data abstractions in terms of old ones and allowing
dynamic selection of types.
All types in Ada 83 were static and thus Ada 83 was not classed as a truly object
oriented language but as an object based language. However, all later versions of
Ada include the essential functionality associated with OOP such as type extension
and dynamic polymorphism.

https://doi.org/10.1017/9781009181358.004 Published online by Cambridge University Press


8 Introduction

We are, as ever, probably too close to the current scene to achieve a proper
perspective. Data abstraction in Ada 83 seems to have been not quite perfect, just
as Fortran expression abstraction and Algol 60 control abstraction were imperfect
in their day. It remains to be seen just how well Ada now provides what we might
call ‘object abstraction’. Indeed it might well be that inheritance and other aspects
of OOP turn out to be unsatisfactory by obscuring the details of types although not
hiding them completely; this could be argued to be an abstraction leak making the
problems of program maintenance even harder.
A brief survey of how Ada relates to other languages would not be complete
without mention of C and C++. These have a completely different evolutionary trail
to the classic Algol–Pascal–Ada route.
The origin of C can be traced back to the CPL language devised by Strachey,
Barron and others in the early 1960s. This was intended to be used on major new
hardware at Cambridge and London universities but proved hard to implement.
From it emerged the simple system programming language BCPL and from that B
and then C. The essence of BCPL was the array and pointer model which abandoned
any hope of strong typing and (with hindsight) a proper mathematical model of the
mapping of the program onto a computing engine. Even the use of := for assignment
was lost in this evolution which reverted to the confusing use of = as in Fortran.
Having hijacked = for assignment, C uses == for equality thereby conflicting with
several hundred years of mathematical usage. About the only feature of the elegant
CPL remaining in C is the unfortunate braces {} and the associated compound
statement structure which was abandoned by many other languages in favour of the
more reliable bracketed form originally proposed by Algol 68. It is again tragic to
observe that Java has used the familiar but awful C style. The very practical
problems with the C notation are briefly discussed in Chapter 2.
Of course there is a need for a low level systems language with functionality
like C. It is, however, unfortunate that the interesting structural ideas in C++ have
been grafted onto the fragile C foundation. As a consequence although C++ has
many important capabilities for data abstraction, including inheritance and
polymorphism, it is all too easy to break these abstractions and create programs that
violently misbehave or are exceedingly hard to understand and maintain. Java is
free from most of these flaws but persists with anarchic syntax.
The designers of Ada 95 incorporated the positive dynamic facilities of the kind
found in C++ onto the firm foundation provided by Ada 83. The designers of Ada
2005 and Ada 2012 have added further appropriate good ideas from Java. But the
most important step taken by Ada 2012 was to include facilities for ‘programming
by contract’ which in a sense is the ultimate form of abstraction. Ada 2022 adds
further features of this nature.
Ada thus continues to advance along the evolution of abstraction. It
incorporates full object abstraction in a way that is highly reliable without incurring
excessive run-time costs.

1.4 Structure and objectives of this book

L earning a programming language is a bit like learning to drive a car. Certain key
things have to be learnt before any real progress is possible. Although we need
not know how to use the cruise control, nevertheless we must at least be able to start

https://doi.org/10.1017/9781009181358.004 Published online by Cambridge University Press


1.4 Structure and objectives of this book 9

the engine, steer, and brake. So it is with programming languages. We do not need
to know all about Ada before we can write useful programs but quite a lot must be
learnt. Moreover, many virtues of Ada become apparent only when writing large
programs just as many virtues of a Rolls-Royce are not apparent if we only use it to
drive to the local store.
This book is not an introduction to programming but an overall description of
programming in Ada. It is assumed that the reader will have significant experience
of programming in some other language such as Pascal, C or Java (or earlier
versions of Ada). But a specific knowledge of any particular language is not
assumed.
This book is in four main parts. The first part, Chapters 1 to 4, is an extensive
overview of most of the language and covers enough material to enable a wide
variety of programs to be written; it also lays the foundation for understanding the
rest of the material.
The second part, Chapters 5 to 11, covers the traditional algorithmic parts of the
language and roughly corresponds to the domain addressed by Pascal or C although
the detail is much richer. The third part, Chapters 12 to 22, covers modern and
exciting material associated with data abstraction, programming in the large, OOP,
contracts, and parallel processing.
Finally, the fourth part, Chapters 23 to 27, completes the story by discussing the
predefined environment, interfacing to the outside world and the specialized
annexes; the concluding chapter also pulls together a number of threads that are
slightly dispersed in the earlier chapters and finishes with an introduction to SPARK.
There are also six complete program examples which are interspersed at various
points. The first follows Chapter 4 and illustrates various aspects of OOP. Others
follow Chapters 11, 13, 22, 23 and 25 and illustrate access types, data abstraction,
generics and tasking, string handling, and storage pools respectively. These
examples illustrate how the various components provided by Ada can be fitted
together to make a complete program. The full text of these programs including
additional comments and other explanatory material will be found on the associated
website.
Most sections contain exercises. They are an integral part of the discussion and
later sections often use the results of earlier exercises. Solutions to all exercises will
be found on the website.
Most chapters end with a short checklist of key points and a brief summary of
what was new in Ada 2012 and what is new in Ada 2022 and in most cases provides
a cross reference to Appendix 4 for further details.
Other appendices are provided in order to make this book reasonably self-
contained. They cover matters such as reserved words, attributes, aspects, pragmas,
and restrictions. There is also a glossary of terms and the complete syntax organized
to correspond to the order in which the topics are introduced. The book concludes
with a Bibliography and Index.
This book includes references to Ada Issues. These are the reports of the Ada
Rapporteur Group (ARG) which analyses technical queries and drafts the new Ada
standards from time to time. Since Ada 2012 became an ISO standard, a small
number of improvements to the language were made resulting in the 2016
Corrigendum. The evolution towards Ada 2022 is similarly described by Ada
Issues. The relevant Issues are listed in the Index.

https://doi.org/10.1017/9781009181358.004 Published online by Cambridge University Press


10 Introduction

This book covers all aspects of Ada but does not explore every pathological
situation. Its purpose is to describe the effect of and intended use of the features of
Ada. In a few areas the discussion is incomplete; these are areas such as system
dependent programming, input–output, and the specialized annexes. System
dependent programming (as its name implies) is so dependent upon the particular
implementation that only a brief overview seems appropriate. Input–output,
although important, does not introduce new concepts but is rather a mass of detail;
again a simple overview is presented. And, as their name implies, the specialized
annexes address the very specific needs of certain communities; to cover them in
detail would make this book excessively long and so only an overview is provided.
Further details of these areas can be found in the Ada Reference Manual (the
ARM) which is referred to from time to time. The appendices are mostly based upon
material drawn from the ARM. There is also an extended form of the reference
manual known as the Annotated Ada Reference Manual (the AARM) – this includes
much embedded commentary and is aimed at the language lawyer and compiler
writer. These documents will all be found on the Ada website as described in the
Bibliography.

1.5 References

T he references given here are to the formal standardization documents describing


the various versions of the Ada Programming Language. References to other
documents will be found in the Bibliography.

1 United States Department of Defense. Reference Manual for the Ada


Programming Language (ANSI/MIL-STD-1815A). Washington DC, 1983.
2 International Organization for Standardization. Information technology –
Programming languages – Ada. Ada Reference Manual. ISO/IEC
8652:1995(E).
3 International Organization for Standardization. Information technology –
Programming languages – Ada. Technical Corrigendum 1. ISO/IEC
8652:1995/COR.1:2001.
4 International Organization for Standardization. Information technology –
Programming languages – Ada. Amendment 1. ISO/IEC
8652:1995/AMD.1:2006.
5 International Organization for Standardization. Information technology –
Programming languages – Ada. Ada Reference Manual. ISO/IEC
8652:2012(E).
6 International Organization for Standardization. Information technology –
Programming languages – Ada. Technical Corrigendum 1. ISO/IEC
8652:2012(E)/COR.1:2016.

https://doi.org/10.1017/9781009181358.004 Published online by Cambridge University Press


2 Simple Concepts

2.1 Key goals 2.5 Access types


2.2 Overall structure 2.6 Errors and exceptions
2.3 The scalar type model 2.7 Terminology
2.4 Arrays and records

T his is the first of three chapters covering in outline the main goals, concepts and
features of Ada. Enough material is given in these chapters to enable the reader
to write significant programs. It also allows the reader to create a framework in
which the exercises and other fragments of program can be executed, if desired,
before all the required topics are discussed in depth.
The material covered in this chapter corresponds approximately to that in
simple languages such as Pascal and C.

2.1 Key goals

A da is a large language since it addresses many important issues relevant to the


programming of practical systems in the real world. It is much larger than
Pascal which is really only suitable for training purposes and for small personal
programs. Ada is similarly much larger than C although perhaps of the same order
of size as C++. But a big difference is the stress which Ada places on integrity and
readability. Some of the key issues in Ada are

• Readability – professional programs are read much more often than they are
written. So it is important to avoid a cryptic notation such as in APL which,
although allowing a program to be written down quickly, makes it almost
impossible to be read except perhaps by the original author soon after it was
written.
• Strong typing – this ensures that each object has a clearly defined set of values
and prevents confusion between logically distinct concepts. As a consequence
many errors are detected by the compiler which in other languages (such as C)
can lead to an executable but incorrect program.

11

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


12 Simple concepts

• Programming in the large – mechanisms for encapsulation, separate


compilation and library management are necessary for the writing of portable
and maintainable programs of any size.
• Exception handling – it is a fact of life that programs of consequence are
rarely perfect. It is necessary to provide a means whereby a program can be
constructed in a layered and partitioned way so that the consequences of
unusual events in one part can be contained.
• Data abstraction – extra portability and maintainability can be obtained if the
details of the representation of data are kept separate from the specifications of
the logical operations on the data.
• Object oriented programming – in order to promote the reuse of tested code,
the type flexibility associated with OOP is important. Type extension
(inheritance), polymorphism and late binding are all desirable especially when
achieved without loss of type integrity.
• Tasking – for many applications it is important to conceive a program as a
series of parallel activities rather than just as a single sequence of actions.
Building appropriate facilities into a language rather than adding them via calls
to an operating system gives better portability and reliability.
• Generic units – in many cases the logic of part of a program is independent of
the types of the values being manipulated. A mechanism is therefore necessary
for the creation of related pieces of program from a single template. This is
particularly useful for the creation of libraries.
• Communication – programs do not live in isolation and it is important to be
able to communicate with systems possibly written in other languages.

An overall theme in the design of Ada was concern for the programming
process as a human activity. An important aspect of this is enabling errors to be
detected early in the overall process. For example a single typographical error in
Ada usually results in a program that does not compile rather than a program that
still compiles but does the wrong thing. We shall see some examples of this in
Section 2.6.

2.2 Overall structure

A n important objective of software engineering is to reuse existing pieces of


program so that detailed new coding is kept to a minimum. The concept of a
library of program components naturally emerges and an important aspect of a
programming language is therefore its ability to access the items in a library.
Ada recognizes this situation and introduces the concept of library units. A
complete Ada program is conceived as a main subprogram (itself a library unit)
which calls upon the services of other library units. These library units can be
thought of as forming the outermost lexical layer of the total program.
The main subprogram takes the form of a procedure of an appropriate name.
The service library units can be subprograms (procedures or functions) but they are
more likely to be packages. A package is a group of related items such as
subprograms but may contain other entities as well.

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


2.2 Overall structure 13

Suppose we wish to write a program to print out the square root of some
number. We can expect various library units to be available to provide us with a
means of computing square roots and performing input and output. Our job is
merely to write a main subprogram to use these services as we wish.
We will suppose that the square root can be obtained by calling a function in
our library whose name is Sqrt. We will also suppose that our library includes a
package called Simple_IO containing various simple input–output facilities. These
facilities might include procedures for reading numbers, printing numbers, printing
strings of characters and so on.
Our program might look like

with Sqrt, Simple_IO;


procedure Print_Root is
use Simple_IO; -- declarations here
X: Float;
begin
Get(X); -- statements here
Put(Sqrt(X));
end Print_Root;

The program is written as a procedure called Print_Root preceded by a with clause


giving the names of the library units which it wishes to use. Between is and begin
we can write declarations, and between begin and end we write statements. Broadly
speaking, declarations introduce the entities we wish to manipulate and statements
indicate the sequential actions to be performed.
We have introduced a variable X of type Float which is a predefined language
type. Values of this type are a set of floating point numbers and the declaration of
X indicates that X can have values only from this set. A value is assigned to X by
calling the procedure Get which is in our package Simple_IO.
Writing
use Simple_IO;

gives us immediate access to the facilities in the package Simple_IO. If we had


omitted this use clause we would have had to write
Simple_IO.Get(X);

in order to indicate where Get was to be found.


The program then calls the procedure Put in the package Simple_IO with a para-
meter which in turn is the result of calling the function Sqrt with the parameter X.
Some small-scale details should be noted. Statements and declarations all
terminate with a semicolon; this is like C but unlike Pascal where semicolons are
separators rather than terminators. The program contains various words such as
procedure, Put and X. These fall into two categories. A few (73 in Ada 2012) such
as procedure and is are used to indicate the structure of the program; they are
reserved words and can be used for no other purpose. All others, such as Put and X,
can be used as identifiers for whatever purpose we desire. Some of these, such as
Float in the example, have a predefined meaning but we can nevertheless reuse them
although it might be confusing to do so. For clarity in this book we write the

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


14 Simple concepts

reserved words in lower case bold and use leading capitals for all others. This is a
matter of style; the language rules do not distinguish the two cases except when we
consider the manipulation of characters themselves. Note also how the underline
character is used to break up long identifiers to increase readability.
Finally, observe that the name of the procedure, Print_Root, is repeated between
the final end and the terminating semicolon. This is optional but is recommended
so as to clarify the overall structure although this is obvious in a small example such
as this.
Our program is very simple; it might be more useful to enable it to cater for a
whole series of numbers and print out each answer on a separate line. We could stop
the program somewhat arbitrarily by giving it a value of zero.

with Sqrt, Simple_IO;


procedure Print_Roots is
use Simple_IO;
X: Float;
begin
Put("Roots of various numbers");
New_Line(2);
loop
Get(X);
exit when X = 0.0;
Put(" Root of "); Put(X); Put(" is ");
if X < 0.0 then
Put("not calculable");
else
Put(Sqrt(X));
end if;
New_Line;
end loop;
New_Line;
Put("Program finished");
New_Line;
end Print_Roots;

The output has been enhanced by calling further procedures New_Line and Put
in the package Simple_IO. A call of New_Line outputs the number of new lines
specified by the parameter (of the predefined type Integer); the procedure New_Line
has been written in such a way that if no parameter is supplied then a default value
of 1 is assumed. There are also calls of Put with a string as argument. This is a
different procedure from the one that prints the number X. The compiler
distinguishes them by the different types of parameters. Having more than one
subprogram with the same name is known as overloading. Note also the form of
strings; this is a situation where the case of the letters does matter.
Various new control structures are also introduced. The statements between
loop and end loop are repeated until the condition X = 0.0 in the exit statement is
found to be true; when this is so the loop is finished and we immediately carry on
after end loop. We also check that X is not negative; if it is we output the message
‘not calculable’ rather than attempting to call Sqrt. This is done by the if statement;

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


2.2 Overall structure 15

if the condition between if and then is true, then the statements between then and
else are executed, otherwise those between else and end if are executed.
The general bracketing structure should be observed; loop is matched by end
loop and if by end if. All the control structures of Ada have this closed form rather
than the open form of Pascal and C which can lead to poorly structured and
incorrect programs.
We will now consider in outline the possible general form of the function Sqrt
and the package Simple_IO that we have been using.
The function Sqrt will have a structure similar to that of our main subprogram;
the major difference will be the existence of parameters.

function Sqrt(F: Float) return Float is


R: Float;
begin
... -- compute value of Sqrt(F) in R
return R;
end Sqrt;

We see here the description of the formal parameters (in this case only one) and
the type of the result. The details of the calculation are represented by the comment
which starts with a double hyphen. The return statement is the means by which the
result of the function is indicated. Note the distinction between a function which
returns a result and is called as part of an expression, and a procedure which does
not have a result and is called as a single statement.
The package Simple_IO will be in two parts: the specification which describes
its interface to the outside world, and the body which contains the details of how it
is implemented. If it just contained the procedures that we have used, its
specification might be

package Simple_IO is
procedure Get(F: out Float);
procedure Put(F: in Float);
procedure Put(S: in String);
procedure New_Line(N: in Integer := 1);
end Simple_IO;

The parameter of Get is an out parameter because the effect of a call such as Get(X);
is to transmit a value out from the procedure to the actual parameter X. The other
parameters are all in parameters because the value goes in to the procedures. The
parameter mode can be omitted and is then taken as in by default. There is a third
mode in out which enables the value to go both ways. Both functions and
procedures can have parameters of all modes. We usually give the mode in for
procedures explicitly but omit it for functions.
Only a part of the procedures occurs in the package specification; this part is
known as the procedure specification and just gives enough information to enable
the procedures to be called.
We see also the two overloaded specifications of Put, one with a parameter of
type Float and the other with a parameter of type String. Finally, note how the
default value of 1 for the parameter of New_Line is indicated.

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


16 Simple concepts

The package body for Simple_IO will contain the full procedure bodies plus any
other supporting material needed for their implementation and is naturally hidden
from the outside user. In vague outline it might look like

with Ada.Text_IO;
package body Simple_IO is
procedure Get(F: out Float) is
...
end Get;
... -- other procedures similarly
end Simple_IO;

The with clause shows that the implementation of the procedures in Simple_IO
uses the more general package Ada.Text_IO. The notation indicates that Text_IO is
a child package of the package Ada. It should be noted how the full body of Get
repeats the procedure specification which was given in the corresponding package
specification. (The procedure specification is the bit up to but not including is.)
Note that the package Ada.Text_IO really exists whereas Simple_IO is a figment of
our imagination made up for the purpose of this example. We will say more about
Ada.Text_IO in Chapter 4.
The example in this section has briefly revealed some of the overall structure
and control statements of Ada. One purpose of this section has been to stress that
the idea of packages is one of the most important concepts in Ada. A program
should be conceived as a number of components which provide services to and
receive services from each other.
Finally, note that there is a special package Standard which exists in every
implementation and contains the declarations of all the predefined identifiers such
as Float and Integer. Access to Standard is automatic and it does not have to be
mentioned in a with clause. It is discussed in detail in Chapter 23.

Exercise 2.2

1 Suppose that the function Sqrt is not on its own but in a package Simple_Maths
along with other mathematical functions Log, Ln, Exp, Sin and Cos. By analogy
with the specification of Simple_IO, write the specification of such a package.
How would the program Print_Roots need to be changed?

2.3 The scalar type model

W e have said that one of the key benefits of Ada is its strong typing. This is well
illustrated by the enumeration type. Consider
declare
type Colour is (Red, Amber, Green);
type Fish is (Cod, Hake, Salmon);
X, Y: Colour;
A, B: Fish;
begin

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


2.3 The scalar type model 17

X := Red; -- ok
A := Hake; -- ok
B := X; -- illegal
...
end;

This fragment of program is a block which declares two enumeration types


Colour and Fish, and two variables of each type, and then performs various
assignments. The declarations of the types give the allowed values of the types.
Thus the variable X can only take one of the three values Red, Amber or Green. The
fundamental rule of strong typing is that we cannot assign a value of one type to a
variable of a different type. So we cannot mix up colours and fishes and thus our
(presumably accidental) attempt to assign the value of X to B is illegal and will be
detected during compilation.
Four enumeration types are predefined in the package Standard. One is
type Boolean is (False, True);

which plays a key role in control flow. Thus the predefined relational operators such
as < produce a result of this type and such a value follows if as in
if X < 0.0 then

The other predefined enumeration types are Character, Wide_Character and Wide_
Wide_Character whose values are the 8-bit ISO Latin-1, the 16-bit ISO Basic
Multilingual Plane and the full 32-bit ISO 10646 characters; these types naturally
play an important role in input–output. Their literal values include the printable
characters and these are represented by placing them in single quotes thus 'X' or 'a'
or indeed '''.
The other fundamental types are the numeric types. One way or another, all
other data types are built out of enumeration types and numeric types. The two
major classes of numeric types are the integer types and floating point types (there
are also fixed point types which are rather obscure and deserve no further mention
in this overview). The integer types are further subdivided into signed integer types
(such as Integer) and unsigned or modular types. All implementations have the
types Integer and Float. An implementation may also have other predefined numeric
types, Long_Integer, Long_Float, Short_Float and so on. There will also be specific
integer types for an implementation depending upon the supported word lengths
such as Integer_16 and unsigned types such as Unsigned_16.
One of the problems of numeric types is how to obtain both portability and
efficiency in the face of variation in machine architecture. In order to explain how
this is done in Ada it is convenient to introduce the concept of a derived type. (We
will deal with derived types in more detail in the next chapter when we come to
object oriented programming.)
The simplest form of derived type introduces a new type which is almost
identical to an existing type except that it is logically distinct. If we write
type Light is new Colour;

then Light will, like Colour, be an enumeration type with literals Red, Amber and
Green. However, values of the two types cannot be arbitrarily mixed since they are

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


18 Simple concepts

logically distinct. Nevertheless, in recognition of the close relationship, a value of


one type can be converted to the other by explicitly using the destination type name.
So we can write

declare
type Light is new Colour;
C: Colour;
L: Light;
begin
L := Amber; -- the light amber, not the colour
C := Colour(L); -- explicit conversion
...
end;

whereas a direct assignment


C := L; -- illegal

would violate the strong typing rule and this violation would be detected during
compilation.
Returning now to the numeric types, if we write

type My_Float is new Float;

then My_Float will have all the operations (+, - etc.) of Float and in general can be
considered as equivalent. Now suppose we transfer the program to a different
computer on which the predefined type Float is not so accurate and that Long_Float
is necessary. Assuming that the program has been written using My_Float rather
than Float then replacing the declaration of My_Float by

type My_Float is new Long_Float;

is the only change necessary. We can actually do better than this by directly stating
the precision that we require, thus

type My_Float is digits 7;

will cause My_Float to be based on the smallest predefined type with at least 7
decimal digits of accuracy.
A similar approach is possible with integer types so that rather than using the
predefined types we can give the range of values required thus

type My_Integer is range -1000_000 .. +1000_000;

The point of all this is that it is not good practice to use the predefined numeric
types directly when writing professional programs which may need to be portable.
However, for simplicity, we will generally use the types Integer and Float in
examples in most of this book. We will say no more about numeric types for the
moment except that all the expected operations apply to all integer and floating
types.

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


2.4 Arrays and records 19

2.4 Arrays and records

A da naturally enables the creation of composite array and record types. Arrays
may actually be declared without giving a name to the underlying type (the
type is then said to be anonymous) but records always have a type name.
As an example of the use of arrays suppose we wish to compute the successive
rows of Pascal’s triangle. This is usually represented as shown in Figure 2.1. The
reader will recall that the rows are the coefficients in the expansion of (1 + x)n and
that a neat way of computing the values is to note that each one is the sum of the
two diagonal neighbours in the row above.
Suppose that we are interested in the first ten rows. We can declare an array
Pascal to hold such a row and a variable N to hold the row number by

Pascal: array (0 .. 10) of Integer;


N: Integer;

If the current values of the array Pascal correspond to row n–1, with the component
Pascal(0) being 1, then the next row can be computed in a similar array Next by

Next(0) := 1;
for I in 1 .. N-1 loop
Next(I) := Pascal(I-1) + Pascal(I);
end loop;
Next(N) := 1;

and then the array Next could be copied into the array Pascal.
This illustrates another form of loop statement where a controlled variable I
takes successive values from a range; the variable is automatically declared to be of
the type of the range which in this case is Integer. Note that the intermediate array
Next could be avoided by iterating backwards over the array; we indicate this by
writing reverse in front of the range thus
Pascal(N) := 1;
for I in reverse 1 .. N-1 loop
Pascal(I) := Pascal(I-1) + Pascal(I);
end loop;

We can also declare arrays of several dimensions. So if we wanted to keep all


the rows of the triangle we might declare
1
1 1
1 2 1
1 3 3 1
1 4 6 4 1
1 5 10 10 5 1

Figure 2.1 Pascal’s triangle.

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


20 Simple concepts

Pascal2: array (0 .. 10, 0 .. 10) of Integer;

and then the loop for computing row n would be

Pascal2(N, 0) := 1;
for I in 1 .. N-1 loop
Pascal2(N, I) := Pascal2(N-1, I-1) + Pascal2(N-1, I);
end loop;
Pascal2(N, N) := 1;

We have declared the arrays without giving a name to their type. We could
alternatively have written

type Row is array (0 .. Size) of Integer;


Pascal, Next: Row;

where we have given the name Row to the type and then declared the two arrays
Pascal and Next. There are advantages to this approach as we shall see later.
Incidentally, the bounds of an array do not have to be constant, they could be any
computed values such as the value of some variable Size.
We conclude this brief discussion of arrays by noting that the type String which
we encountered in Section 2.2 is in fact an array whose components are of the
enumeration type Character. Its declaration (in the package Standard) is

type String is array (Positive range <>) of Character;

and this illustrates a form of type declaration which is said to be indefinite because
it does not give the bounds of the array; these have to be supplied when an object is
declared

A_Buffer: String(1 .. 80);

The identifier Positive in the declaration of the type String denotes what is
known as a subtype of Integer; values of the subtype Positive are the positive
integers and so the bounds of all arrays of type String must also be positive – the
lower bound is of course typically 1 but need not be.
A record is an object comprising a number of named components typically of
different types. We always have to give a name to a record type. If we were
manipulating a number of buffers then it would be convenient to declare a record
type containing the buffer and an indication of the start and finish of that part of the
buffer actually containing useful data.

type Buffer is
record
Data: String(1 .. 80);
Start, Finish: Integer;
end record;

An individual buffer could then be declared by


My_Buffer: Buffer;

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


2.4 Arrays and records 21

and the components of the buffer can then be manipulated using a dotted notation
to select the individual components

My_Buffer.Start := 1;
My_Buffer.Finish := 3;
My_Buffer.Data(1 .. 3) := "XYZ";

Note that the last statement assigns values to the first three components of the array
My_Buffer.Data using a so-called slice.
Whole array and record values can be created using aggregates which are
simply a set of values in parentheses separated by commas.
Thus we could assign appropriate values to Pascal and to My_Buffer by

Pascal(0 .. 4) := (1, 4, 6, 4, 1);


My_Buffer := (Data => ('X', 'Y', 'Z', others => ' '), Start => 1, Finish => 3);

where in the latter case we have in fact assigned all 80 values to the array
My_Buffer.Data and used others so that after the three useful characters the
remainder of the array is padded with spaces. Note the nesting of parentheses and
the optional use of named notation for the record components.
This concludes our brief discussion on simple arrays and records. In the next
chapter we will show how record types can be extended.

Exercise 2.4

1 Write statements to copy the array Next into the array Pascal.
2 Write a nested loop to compute all the rows of Pascal’s triangle in the two-
dimensional array Pascal2.
3 Declare a type Month_Name and then declare a type Date with components
giving the day, month, and year. Then declare a variable Today and assign
Queen Victoria’s date of birth to it (or your own).

2.5 Access types

T he previous section showed how the scalar types (numeric and enumeration
types) may be composed into arrays and records. The other vital means for
creating structures is through the use of access types (the Ada name for pointer
types); access types allow list processing and are typically used with record types.
The explicit manipulation of pointers or references has been an important
feature of most languages since Algol 68. References rather dominated Algol 68
and caused problems and the corresponding pointer facility in Pascal is rather
austere. The pointer facility in C on the other hand provides raw flexibility which is
open to abuse and quite insecure and thus the cause of many wrong programs.
Ada provides both a high degree of reliability and considerable flexibility
through access types. A full description will be found in Chapter 11 but the
following brief description will be useful for discussing polymorphism in the next
chapter.

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


22 Simple concepts

Ada access types must explicitly indicate the type of data to which they refer.
The most general form of access types can refer to any data of the type concerned
but we will restrict ourselves in this overview to applications which just refer to
data declared in a storage pool (the Ada term for a heap).
For example suppose we wanted to declare various buffers of the type Buffer in
the previous section. We might write
Handle: access Buffer;
...
Handle := new Buffer;

This allocates a buffer in the storage pool and sets a reference to it into the variable
Handle. We can then refer to the various components of the buffer indirectly using
the variable Handle
Handle.Start := 1;
Handle.Finish := 3;

and we can refer to the complete record as Handle.all. Note that Handle.Start is
strictly an abbreviation for Handle.all.Start.
Access types are of particular value for list processing where one record
structure contains an access value to another record structure. The classic example
which we will encounter in many forms is typified by
type Cell is
record
Next: access Cell;
Value: Data;
end record;

The type Cell is a record containing a component Next which can refer to
another similar record plus a component of some type Data. An example of the use
of this sort of construction will be found in the next chapter.
Sometimes it is important to give a name to an access type. We can rewrite the
above example so that the component Next is of a named type by first using an
incomplete type thus

type Cell; -- incomplete declaration


type Cell_Ptr is access Cell;
type Cell is -- the completion
record
Next: Cell_Ptr;
Value: Data;
end record;

Using this two stage approach and naming the access type is necessary if we are
doing our own control of storage as described in Section 25.4.
Access types often refer to record types as in these examples but can refer to
any type. Access types may also be used to refer to subprograms and this is
particularly important for certain repetitive operations and when communicating
with programs in other languages.

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


2.6 Errors and exceptions 23

2.6 Errors and exceptions

W e introduce this topic by considering what would have happened in the


example in Section 2.2 if we had not tested for a negative value of X and
consequently called Sqrt with a negative argument. Assuming that Sqrt has itself
been written in an appropriate manner then it clearly cannot deliver a value to be
used as the parameter of Put. Instead an exception will be raised. The raising of an
exception indicates that something unusual has happened and the normal sequence
of execution is broken. In our case the exception might be Constraint_Error which
is a predefined exception declared in the package Standard. If we did nothing to
cope with this possibility then our program would be terminated and no doubt the
Ada Run Time System will give us a rude message saying that our program has
failed and why. We can, however, look out for an exception and take remedial
action if it occurs. In fact we could replace the conditional statement
if X < 0.0 then
Put("not calculable");
else
Put(Sqrt(X));
end if;

by the block
begin
Put(Sqrt(X));
exception
when Constraint_Error =>
Put("not calculable");
end;

If an exception is raised by the sequence of statements between begin and


exception, then control immediately passes to the one or more statements following
the handler for that exception and these are obeyed instead. If there were no handler
for the exception (it might be another exception such as Storage_Error) then control
passes up the nested sequence of calls until we come to an appropriate handler or
fall out of the main subprogram, which then becomes terminated as we mentioned
with a message from the Run Time System.
The above example is not a good illustration of the use of exceptions since the
event we are guarding against can easily be tested for directly. Nevertheless it does
show the general idea of how we can look out for unexpected events, and leads us
into a brief consideration of errors in general.
From the linguistic viewpoint, an Ada program may be incorrect for various
reasons. There are four categories according to how they are detected.

• Many errors are detected by the compiler – these include simple punctuation
mistakes such as leaving out a semicolon or attempting to violate the type rules
such as mixing up colours and fishes. In these cases the program is said to be
illegal and will not be executed.

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


24 Simple concepts

• Other errors are detected when the program is executed. An attempt to find the
square root of a negative number or divide by zero are examples of such errors.
In these cases an exception is raised as we have just seen.
• There are also certain situations where the program breaks the language rules
but there is no simple way in which this violation can be detected. For example
a program should not use a variable before a value is assigned to it. In cases like
this the behaviour is not predictable but will nevertheless lie within certain
bounds. Such errors are called bounded errors.
• In more extreme situations there are some kinds of errors which can lead to
quite unpredictable behaviour. In these (quite rare) cases we say that the
behaviour is erroneous.
Finally, there are situations where, for implementation reasons, the language
does not prescribe the order in which things are to be done. For example, the order
in which the parameters of a procedure call are evaluated is not specified. If the
behaviour of a program does depend on such an order then it is not considered to be
incorrect but just not portable.
We mentioned earlier that an overall theme in the design of Ada was concern
for correctness and that errors should be detected early in the programming process.
As a simple example consider a fragment of program controlling the crossing gates
on a railroad. First we have an enumeration type describing the state of a signal
type Signal is (Danger, Caution, Clear);

and then perhaps


if The_Signal = Clear then
Open_Gates;
Start_Train;
end if;

It is instructive to consider how this might be written in C and then to consider


the consequences of various simple programming errors. Enumeration types in C
are not strongly typed and essentially just provide names for integer (int) constants
with the values 0, 1, 2 representing the three states. This has potential for errors
because there is nothing in C that can prevent us from assigning a silly value such
as 4 to a signal whereas it is not even possible to attempt such a thing when using
the Ada enumeration type.
The corresponding text in C might be
if (the_signal == clear)
{
open_gates();
start_train();
}

It is interesting to consider what would happen in the two languages if we make


various typographical errors. Suppose first that we accidentally type an extra
semicolon at the end of the first line. The Ada program then fails to compile and the
error is immediately drawn to our attention; the C program however still compiles
and the condition is ignored (since it then controls no statements). The C program

https://doi.org/10.1017/9781009181358.005 Published online by Cambridge University Press


Another random document with
no related content on Scribd:
signet of Joab, who was sent to collect tribute from them in the time
of the son of David.
In 1844 there still existed an ancient inscription in Hebrew graven
on a stone in the Dra country, which was said to be as follows: ‫עד כאן‬
‫ הגיץ יואב בן צרויה לקבל המס‬which is interpreted thus, ‘So far as this
place came Joab Ben (son of) Serruia to receive the tribute.’
Joab, chief of the army of King David, is called in the recognised
translation of the Bible ‘the son of Zeruiah.’
A drunken Rabbi, named Judah Azalia, called on me the other
day; he has been travelling for three years in the southern districts of
Morocco, and he visited also many of the towns and villages
bordering on the Great Desert beyond Dra, which province you will
find marked in the map. Judah was half intoxicated, as usual, when
he visited me, and he left Tangier before I could entrap him in a
sober moment. Judah had travelled much in the East, had read a
number of curious old books, and was full of traditions he had picked
up in the interior of this country; but all he told me was in such a
jumbled state that I could not retain it, but requested the learned and
drunken Rabbi to commit to paper the subject-matter of our
conversation.
I send you a translation of the Hebrew original.
From the preface you will expect much; but, alas! there is only the
phantom of a skeleton, whose doubtful apparition leaves us big with
fancies and uncertainty. The man knows nothing of geography or
history, except the Bible.
You will be struck with the tradition of the Jews of the interior
respecting the tribe of Naphtali, the tombs, &c. I regret he has
curtailed greatly his verbal statements; for, amongst other curious
matter, he told me of a burial-ground of the Jews in the interior—
some mile or mile and a half in circumference.
The story about the Israelite warriors is curious, but the staining of
the hair before battle looks more like the Goths.
Judah supposes that Wadan is much nearer the Red Sea than it
really is; but if the Naphtali tribes fled from captivity, through Central
Africa, towards Dra and the South of Morocco, one of the first towns
or villages at which they would have found means of subsistence,
would have been Wadden or Yaden.
The names of the places and towns are so different from those
given in our maps, as indeed they always appear to be when
mentioned by natives of the interior, that I can hardly recognise
them, and have no time just now to refer to my maps of Africa.
Judah has promised to send me a further memorandum, but the
fumes of ‘agua ardiente’ will, I fear, stifle all recollection of his
promise.

Translation from the Hebrew.


I am about to give a description respecting my brethren of Israel, who, through
captivity, are now dwelling in Western Barbary, and to tell—as far as my
knowledge permits—of their state, their mode of living and genealogy; being in
conformity with what has been related to me by wise old men and persons of
integrity and good faith, incapable of stating an untruth. I will further relate what I
have personally witnessed during the travels of my youth, as also the information I
have obtained from ancient and exact tradition, both in manuscript and in print.

It is well known that when Sennacherib (? Shalmaneser[15]), king of Assyria,


conquered the people of Israel, these (the Israelites), were led into captivity to
Lahleh (? Halah) and Habor. Thence all the Israelite tribe of Naphtali, or the
greater portion thereof, sought refuge in Vaden, a town situated on the limits of
Guinea (meaning Central Africa), which town had at that time direct
communication with Lahleh and Habor. From Vaden they (the Israelites) were
scattered to Daha[16], Tafilelt, and Vakka[17] which are situated on the confines of
the Province of Daha towards Ofran, according to the writings of the pious Rabbi,
Jakob Benisargan, who places Vakka upon the borders of the river of Daha. Thus
were the Israelites spread throughout the interior of Africa.
In Vaden there is a large burial ground of Jews, whose sepulchres are covered
with slabs of stone bearing very intelligible epitaphs. In Vaden there is a
synagogue where fragments of the Pentateuch and of the Prophets, written on
parchment, are to be found.
In Ofran is to be seen a carved stone with a Hebrew inscription which has
existed since the destruction of the first temple. In the burial ground there are
several tombstones bearing epitaphs, of which the genealogy is written in the
Hebrew character but in the Arabic tongue: some of these are dated three hundred
years ago, others go as far back as twelve hundred years.
From Ofran you journey to Eleg[18], where there exists a large congregation of
Jews; exactly as is related by the famous and illustrious Rabbi, Izak Barseset. In
Ofran there stands a building which it is supposed was erected by one of the
ancient kings of Western Barbary. It is constructed with large hewn square stones.
There are also ruins of buildings which are supposed to be Roman.
Then comes the town of Telin, and later that of Thala, where there exists even
at the present time an immense stone, and at its foot is a pool of water. The old
people of the place tell you of a tradition that upon this stone the Israelite warriors
prepared a dye of ‘henna[19]’, with which they dyed their hair before going to
battle. They relate that the number of the said warriors amounted to four hundred
thousand cavalry. It is said that on one occasion the enemies of these warriors
treacherously came to offer peace upon any conditions that might be imposed.
The peace having been concluded on the sacred day of Kipur[20], all the Israelites
were unarmed, but the enemy had hidden their own arms in the sand.
The Israelites, glad to profit by so advantageous a peace—and not suspecting
any treachery—approached the hostile army, perceiving also that they had no
arms, when suddenly a preconcerted signal was given, and the latter, rushing
upon the Israelites, cut them to pieces. One slave alone survived this most fatal
misfortune, and he buried the bodies of the slain. On account of their number he
put ten bodies into each grave, but for the last grave there were only nine bodies,
so the slave—overwhelmed with grief and sorrow—threw himself into the grave to
complete the ten. Even to the present time this spot is called ‘The sepulchre of the
ten.’
At a little distance from Eleg, there is a celebrated fountain called Ras-el-Ain
(the source of the spring), so called because there is a spring of water at forty
fathoms below the surface. The fountain can be followed three days’ journey
irrigating the olive, fig, pomegranate, almond, and palm trees, and the land is also
thereby watered for the cultivation of grain and vegetables.
The following towns or villages are to be noted as having Hebrews among the
population: Zaachian, Lasakia, Takulebat, Torribat, Bardlaiimi, and Taheret[21].
This last-mentioned town is noted for being the birthplace of many learned Jews
and Rabbis in very ancient times. The most celebrated and illustrious Rabbi,
Judah El Hayugni, was born at Taheret. He it was who founded the grammar of our
sacred language.
Beyond Taheret is the town of Lasats, which has a large Jewish population. In it
there are gardens and fruit trees, which are cultivated with great success.
The best limes in Barbary are grown here, and are used in the religious
ceremonies of the Jews throughout Morocco.

Mulai Hashem, a native of Tafilelt, tells me that the Jews are very
numerous in his country. He says there are two races of Jews
among them, one race has been in Tafilelt since eight years previous
to the Hegira of Mohammed, the other having been brought in by a
chief named Mulai Ali, the son of Mulai Hassan.
Mulai Ali, says my informant, had purchased these Jews from
some distant country of the East—where he found them in great
distress—and he gave fifty pieces of money for each: what money
he does not know.
Mulai Hashem says that these two races are thus distinguished.
The older race have the whole head shaved. The colony brought by
Mulai Ali leave a small segment of a circle unshaved on the top of
the forehead. These latter also wear a black cap, somewhat pointed
at the top, where it is made to curl down on one side of the face.
The Jewesses are not dressed like those that live in Tangier, but
in the costume of the Moorish woman, and wear rich dresses with
jewels. They are however to be distinguished from the Moorish
woman by the arrangement of their hair, which the latter draw
backwards from either side of the forehead over the temples to the
back of the head; whereas the Jewesses (unmarried) twist their hair
in circles on the top of the head. The married Jewesses are not
allowed by the law to show their hair. This law, by the way, is not
from the Bible, but is an invention of the Rabbis.
The Jews, said Mulai Hashem, are well treated in Tafilelt, whilst
they behave well and according to the rules laid down for them;
which, by the specimen of one that he gave, appear sufficiently
humiliating—viz. that should a Jew pass or be passed by a Sheríf,
he, the Jew, must take off his shoes; or, if mounted, must dismount,
unless specially absolved by the Sheríf.
He tells me that they exercise all the crafts which are practised in
the country, except tilling the soil. It appears that the Jews
themselves seldom, if ever, accompany the ‘kafilas’ (caravans), but,
he says, they have commercial dealings with the Sudan country.
It would appear that the Tafilelt Jews are much at their ease, if
one may judge from the joking adage—according to Mulai Hashem
common in Tafilelt—that ‘forty Mohammedans work for one Jew.’
Mulai Hashem said that the Filali Jews, or Jews of Tafilelt, speak the
Shloh tongue as well as the Arabic, and whenever they wish to say
what they would not have known to Moors or others they speak in
Hebrew.
A learned Jew of this country tells me that all Arabs and Moors
whose names are composed with Ben are of an Israelitish origin.
Mulai Hashem tells me that the following oath is administered in
his country to the Jews, and that they will rather give back anything
they may have come by unjustly than take so grave an oath:—
‘By God, there is no other God but He, the Eternal and Just—who
uttered His word upon the mighty hill—and by the truth of the
existence of the two palm-trees which meet together over the river
Sebts, and by the Book of Moses—peace be upon him—and by the
Ten Commandments delivered unto Moses, and by all that is
contained in his Book, the Gadi, God forbid that I should add or
diminish in this affair, else may God destroy my memory, and may
the name of my family be never mentioned in the world.’
Sebts is the Arabic for Sabbath, and is here applied to the fabled
river called by the Jews Sabbatyon.
It is not clear what is meant by Gadi.
A Jewish Rabbi, named Benshiten, tells me that two and a half
tribes of Israel are the portion which make up the number of Jews
that are found in Europe and Africa—and the remaining nine and a
half are found to exist on the East of a river which is named
Sabbatyon, and is said to be to the East of Mecca. This river, said
he, has the peculiarity of the stones in its bed fighting with each
other all the week excepting the Sabbath, on which day Hebrews
cannot travel; so that the nine and a half tribes cannot communicate
with their separated brethren.

Mr. Hay, it may be added, was the first to break through some of
the despotic rules imposed by the Moors on the Jews. On his arrival
at Tangier in 1844 the Hebrew interpreters attached to the different
Consulates were obliged to remove—as did their brethren—their
slippers on passing a mosque or other sanctuary. When he paid his
visit of ceremony to the Basha, on succeeding his father as Consul-
General and Political Agent, Mr. Hay went, according to the custom
of those days, in full uniform. He was accompanied by his staff, of
which one member—the Interpreter, Mr. David Sicsu—was a Jew, a
shrewd and able man, who had been attached for some years to the
British Consulate. On their way to the Basha’s residence they
passed the great mosque. Mr. Hay noticed that Sicsu stopped and
took off his shoes; so turning, he called out to him in a loud voice,
that all might hear, ‘What are you doing? Put on your shoes.
Remember you are an English employé and, as such, have all the
privileges of British subjects. If ever you do that again, I shall dismiss
you.’
Also, on his first visit to the Sultan’s Court, in 1846, Mr. Hay
insisted on his Jewish interpreters being allowed to ride about the
capital on mule-back, and to enjoy the same rights and privileges as
granted to other members of his staff.
It is only within the last thirty years that Jews in Morocco—not
foreign employés or protected subjects—have been allowed to
assume the European dress, or to wear yellow slippers or red caps
when in native costume. Formerly they were compelled to confine
themselves to black slippers and caps and the Jewish gaberdine.
CHAPTER X.

DIFFICULTIES OF MR. HAY’S POSITION AT TANGIER. 1846-54.

With characteristic energy and perseverance Mr. Hay


endeavoured to increase the influence and develope the trade of
Great Britain in Morocco, then greatly on the decline. But at every
turn he met with many obstacles. Not the least of these was the
warlike attitude of France towards Morocco as compared with the
peaceful policy of Great Britain. To the ignorant, barbarian Moors
quiet strength appeared to be weakness, while they were in a
corresponding degree impressed by the restless activity of the
French, who, in consequence of the machinations of Abd-el-Kader,
were then on uneasy terms with the Sultan, and left no means
untried to consolidate their influence and to acquire sole
predominance over him. In pursuance of these objects the French
Representatives, with whom Mr. Hay individually was on excellent
terms, were unceasing in their efforts to promote French interests
and gained over to their cause all the most powerful men connected
with the Moorish Court,—not a difficult matter with a corrupt and
venal Government.
The Sultan dared not depend on the countenance of any nation
but the French—fearing that the latter power, if he sought other
protection, might, on the pretext of sending a force in pursuit of Abd-
el-Kader or rebel Algerian tribes, invade Maroquin territory. But the
natives generally were strongly in favour of Great Britain and hostile
to France.
Legitimate commerce, then principally in British hands, was ever
on the decrease, while contraband traffic was largely increasing.
Mr. Hay urged that, to counterbalance French military influence, a
more authoritative tone must be adopted by Great Britain in her
dealings with the Sultan, and that certain commercial concessions
and reforms should be demanded. He also advised that more
frequent visits should be paid by British men-of-war to Moorish ports,
from which some vessel of the French navy was seldom absent,
while British ships were rarely seen. A year later he pointed out that
his rank, as Consul-General and Agent only, militated against his
efforts to increase British influence, since both the French and
Spanish Governments had Ministers accredited to the Moorish
Court, and the Moors, who neither had newspapers of their own nor
read those of other countries, who had no postal system, and no
native society in which Europeans could mingle, estimated the
comparative importance of different nations by the status of their
respective employés.
Mr. Hay’s efforts were not unrecognised by the Foreign Office.
Encouraging letters reached him from the Chief Clerk signifying Lord
Palmerston’s satisfaction, and at the close of 1847 he was promoted
to the rank of Chargé d’Affaires.
It was also owing to Mr. Hay’s persistent representations that
duties on imported goods were, in September, 1848, reduced ten per
cent. The reduction gave fresh impetus to British trade and
prevented its diversion into Franco-Algerian channels which seemed
at one time imminent.
In the meantime the feelings of the people of Morocco were
growing still more in favour of Great Britain and antagonistic to the
policy of the Sultan. This potentate evinced great ill-will to Mr. Hay,
and even threatened at various times to insist on his recall, should
he persist, as hitherto, in enforcing the claims of British subjects.
This ill-will on the part of the Sultan arose, no doubt, in great
measure from his having been erroneously led to believe by evil
advisers in 1844 that Great Britain would employ armed force on
behalf of the Moors, and from his conviction that she had broken
faith in failing to do so.
A better feeling towards Great Britain was brought about,
however, by an act of kindly courtesy on the part of Her Majesty’s
Government. In July, 1849, a British vessel of war was sent to
conduct H.S.M.’s two sons to Alexandria, whence they were to
journey to Mecca, the same vessel afterwards bringing them back.
This act of kindness was received with great gratitude by the Sultan,
and in acknowledgement he shortly after sent to the Queen a
present of wild animals, horses and specimens of Moorish
manufactures. Several Moors accompanied the Sultan’s gift to the
Queen and, on their return, in May, 1850, Mr. Hay wrote to Mr.
Addington, then Chief Clerk at the Foreign Office, telling him of their
delight at their reception:—

The Moors have returned, delighted with their visit to the land of the
Nazarenes. Around my house, groups of respectable men may be seen listening
to the wondrous tales of Kaid Abd-el-Kerim or of my groom. The old chief hunter,
Hadj Abdallah, sits in his village—amidst a motley crowd of Arabs and Rifians—
telling them of the magnificence and wonders of London, and the kindness the
poor Moors received, from the Queen down to the servants that assisted them. He
proclaims loudly to the astonished fanatics that power, wealth, honesty, and charity
are to be found in the land of the Infidel and not in the land of the Moslem.
The Hadj tells me that at one time he had almost lost his reason in thinking
over what he had seen. His stories have amused me as much as they do the
Moors, and I have been almost inclined to publish the ‘Travels of the Hadj,’ or get
my brother to do so, as I am rather lazy about writing when it is not a duty.
All the Moors talk much of the Queen and Prince Albert, who they declare sent
for them more than once. So England and the English are in the mouth of every
Moor since the return of the travellers.

In direct contrast to this exchange of courtesies, the French had


continued their dictatorial policy and the feeling in Morocco ran high
against France.
Thus, in April, 1849, the French Chargé d’Affaires struck his flag
in consequence of an altercation with the Lieutenant-Governor
regarding a courier in French employ who had been imprisoned by
that official. This courier was found carrying letters of a purely private
character from Abd-el-Kader to his former lieutenant, then a State
prisoner at Fas. The Moorish Government refused to release the
courier who eventually died in prison. After much negotiation and
pacific counsel on the part of the Neapolitan Consul, who was in
charge of French interests, and of Mr. Hay—who, as he wrote to a
relative, could not have worked harder to bring about a peaceful
issue, had he been himself a Frenchman—the Moors gave way and
offered every reparation. But French pride was roused. Fresh
complications ensued, and finally all the French subjects at Tangier
and the Ports embarked on board vessels of war. In the meantime
the Sultan had begun to collect troops on the Algerian frontier and
war seemed imminent. Mr. Hay hurried off to El Araish by sea and
interviewed the Moorish Minister for Foreign Affairs who, by an
anomalous—though essentially Moorish—arrangement, resided
there. He succeeded in persuading him to check all warlike
preparations; but it was not till the close of September that matters
were brought to a peaceful termination and the French flag hoisted
and saluted.
In connection with the foregoing events Mr. Hay relates the
following story, which he had from an authentic source.

When relations between France and Morocco were in a critical condition and a
declaration of war seemed imminent, the Sultan sent for Abd-el-Hadi, the Kadi of
his Capital, said to be the wisest man in Morocco, and asked him what he was to
reply to the demands of the French.
‘Refuse the infidel,’ said Abd-el-Hadi. ‘Order the destruction of all your ports;
blow up the fortifications; let every man arm and become, as were his ancestors, a
wandering Arab, and then tell the French to do their worst!’
When Abd-el-Hadi had retired, the Sultan turned to his Uzir and said, ‘The Kadi
ought to have added—Abdicate, encourage anarchy and revolution, and destroy at
once the Empire.’
It may be surmised, however, that Abd-el-Hadi was a wiser man than he
appears. Desirous of humouring his lord and master by recommending war, he yet
put his advice in a light which would show the Sultan the folly of resisting the
French.
Not only was the residence of the Minister for Foreign Affairs at El
Araish most inconvenient at all times to the Representatives—all of
whom lived at Tangier—but it necessitated, as has been seen,
frequent hurried journeys on their part to that port.
On one such occasion, Mr. Hay had proceeded to El Araish by
land to interview Sid Buselham, and had succeeded in getting from
him a reply, which he desired to forward at once to head-quarters by
one of the rare steamers to England due to leave Tangier next
morning. In expectation of this he had, on his way to El Araish,
arranged that four relays of horses were to await his return at
different points of the road between that town and Tangier, a
distance of sixty miles—and, as soon as he had obtained the
Minister’s signature, he mounted and dashed off homewards.
The Governor of El Araish, anxious for the British Agent’s safety
in those troubled times, had given orders that a mounted escort
should also await him with every fresh horse and follow him on the
road. These, however, were unable to keep pace with him. On arrival
at the little town of Azaila, situated about halfway between Tangier
and El Araish, he found no horse prepared for him. Riding at once to
the British Consular Agent’s house, Mr. Hay demanded his horse.
The Agent, a Jew, explained that it was locked up in the stable of the
Basha, who was away, and that the groom was not to be found.
‘Take me to the stable,’ said Mr. Hay, and, calling to four men of the
little crowd of idlers that had gathered, he ordered them to lift a large
log of wood which lay near and direct it as a ram against the door.
‘Now, all together,’ said Mr. Hay. Down came the door with a crash,
and quickly putting his saddle on the fresh horse, and throwing
money to the Agent to repay the damage to the door, he mounted
and rode on.
Before reaching the river Mishra-el-Hashef, some miles to the
west of Tangier, he found his own sturdy pony awaiting him, and
riding this, his favourite mount, he galloped to the river bank where
the ferry, rowed by two men, awaited him. Shouting to them to stand
clear, he jumped his pony into the boat, and out again on reaching
the further side. He arrived at Tangier having ridden the whole
distance in five hours.
The escorts appointed to accompany him returned to their
quarters, having failed to keep Mr. Hay in sight. ‘It was useless,’ said
they. ‘We galloped along behind him but he ran away from us, and
as soon as he had gone a little way ahead he spread large wings
and flew away with his horse!’
As Mr. Hay wore a loose Inverness cape, to protect him from sun
and weather, the fluttering of this may have suggested the idea of
wings.
An account of a curious and unpleasant adventure which befell
Mr. Hay, and which points to the unsettled and fanatical state of the
inhabitants of Tangier at that time is given in the following letter to his
wife’s sister, Mme. Marcussen.

July 29, 1849.


I have also had an affair—and as it may probably be stuffed into some
newspaper which might report my death, as was done once before, I will tell you
about it in a few words.
A few days ago I was accompanying A., perched on her donkey, and the two
children to Madame F.’s. On passing through the little market-place I had remained
rather behind to take care of R., who was holding my hand, when I was assailed
with abuse without the slightest cause by a wild-looking Hadj from the interior—
and, on my calling on the bystanders to arrest him, the fanatic made at me and
struck me a blow in the face and on the shoulder, hitting also by chance poor little
R. I had nothing in my hand but my little gold-headed cane. Of this, however, I
made good use; for I immediately struck the bare head of the Moslem who
instantly fell to the ground, stunned, with a gash of several inches from which
issued torrents of blood, whilst the wretch looked livid and appeared to be
quivering in the convulsions of death. Several of the Hadj’s brethren were near me,
but they all seemed so alarmed at the fate of the wounded man that they did not
venture within reach of my little stick. You may imagine my astonishment at the
effect of such a blow from so small a weapon, and you may imagine also, though I
was justified in defending myself, my horror at the appearance of the wounded
man.
The man was sent to prison and his head examined. The skull was not hurt, but
there was a large gash of the skin and plenty of blood from a severed vein. This
was soon put to rights, and as the wretch had received a good lesson for attacking
a Christian, and all his brethren came to me to intercede for him, as he was about
to embark on board a vessel for Alexandria, I let him out of prison and prevented
Basha giving him the bastinado as he had intended. ‘Voilà tout.’

It may be added in connection with the incident here recounted by


Mr. Hay that, surrounded though he was by a crowd of angry fanatics
—very different in those remote days from the generality of the
native population as known to the tourist in these later and more
civilised times—he stood his ground, alone and undaunted, and the
moment after he had felled his assailant, his only remark was, while
pointing to the fallen man with his stick, ‘Erfed e’jifa’ (Take away the
corpse).
No fear of consequences held back the wild pilgrims who hated
the Christian with the blind, unreasoning hatred of ignorance and
fanaticism; his individuality alone kept them in check, where another
man might have been torn to pieces.
The Basha, after seeing the wounded man, sent to inquire what
manner of sword Mr. Hay had employed which produced such a
peculiar and dangerous wound—and was much astonished when
shown a light but strong cane with a silver gilt head, formerly the
property of Sir Walter Scott, by whom it had been given to Mr. Hay’s
father.
The attitude Mr. Hay had adopted in dealing with the barbarous
Moorish Government, his firm, upright, and frank policy, began to
bear fruit, and in 1850 he writes to his cousin, Mr. R. W. Hay, then
Under-Secretary of State for the Colonies:—

I am glad to find that the straightforward course I have always pursued with this
Government—though often not very flattering to their vanity and fanaticism—
begins to be understood and appreciated, rather than the cajolery they are
accustomed to meet with from others.

On the other hand, to Sir Stratford Canning in February, 1851, he


says:—
In this country there is nought of interest passing. Our Sultan is a fanatic, and is
guided by a set of ignorant and venal ministers, who are doing all they can to ruin
the commerce of the country by a system of monopolies. It is no use talking or
writing to those who, it appears, won’t or can’t understand.
Their disputes with the French, about frontier, &c., have ceased for the
moment, but there are difficulties we must expect to the end of the chapter—or
rather, until Algiers becomes Morocco or Morocco part of Algiers.

The difficulties he anticipated were not long in abeyance. In the


following December, in a letter to Mme. Marcussen, he tells her:—

The French bombarded Salli on the 25th ult., without giving any notice to us
here or to the Sultan or his Government. Not much harm is done to the town: some
thirteen persons killed in all, and the French have five killed and thirty wounded.
One of their steam frigates was compelled to retire from the combat. After the
bombardment they came here, and all the petty affairs they had to settle were
settled at once—as they would have been before the bombardment if they would
only have been inclined to arrange matters amicably. They saluted the town and
peace was concluded. A reference was then made to the Sultan. His Majesty
accepts the peace, but asks for explanations about bombardment; so B.[22] has
taken umbrage and embarks with all the French subjects, or most of them, leaving
the French flag flying and the Sardinian Consul-General in charge. It has been
mere bullying; the strong trampling on the weak.

In the midst of these difficulties Mr. Hay continued to press upon


the Moorish Government the necessity of a more liberal policy in
matters of trade; but French schemes of political aggrandisement
and the natural apathy of the Sultan, combined with fear of France,
for the time rendered his best endeavours fruitless. In 1853 Mr. Hay
seemed as far from his object as ever. Writing in that year to Mme.
Marcussen, he says:—

I have been very busy, and have been compelled to suspend all relations with
the Moorish Court—though I do not strike my flag. I have given them ten days in
which to give way, and have no doubt they will. My demands have reference to our
rights in trade in this country, which we are anxious to place on a better footing, not
only for Great Britain but for Morocco itself and all countries.
The Moorish Government have announced that they send an Envoy to
England; and his object, it is reported, is to complain of the insistance and audacity
which I have shown in this negotiation. I am delighted at this manœuvre because it
will only tend finally to show these people I am acting up to my instructions and the
views of Government. So much for Moorish politics.

Such representations on the part of the Moorish Government to


the British Foreign Office were not likely to bear much weight, as
may be gathered from the following farewell letter addressed to Mr.
Hay by Mr. Addington, then retiring from his post as Chief Clerk at
the Foreign Office.

May 18, 1854.


My dear Sir,
I have been much gratified by the receipt of your letter, written on hearing of
my retirement from the Foreign Office. . . .
No act of mine, while I was in office, is remembered by me with more
satisfaction and confidence than the part I had in forwarding your appointment to
the post which you now enjoy so creditably to yourself and so beneficially to the
public.
Some thought so young an appointment hazardous. I felt satisfied it would
succeed, and I therefore pushed it on so far as it depended on me. And it has
succeeded, and will yet succeed.
Go on, without swerving, in the same track; vigorous but temperate;
straightforward; never condescending to indulge in paltry and un-English intrigue
or tortuosity; but not despising the ‘reculer pour mieux sauter’ principle whenever
you find turning the bull’s flank more likely to succeed than taking him by the
horns; and always remembering that, ‘suaviter in modo, fortiter in re,’ is the real
adage for subduing the world and any individual in it.
I wish you every success, and am ever yours very sincerely,
H. Ch. Addington.
CHAPTER XI.

LIFE AT TANGIER.
Mr. Hay had married, in 1845, a daughter of Mr. Carstensen, a
former Danish Consul-General to Morocco. Except when the
exigencies of a climate which proved very trying in summer for
children of northern race compelled him to send them home, he, with
his wife and young family, resided either at the old Government
House in Tangier or in a villa called by him ‘The Wilderness,’ outside
the walls, which had belonged to his father-in-law. This existence
was only varied by missions to the Court or occasional visits to
England. Beyond the very small European society, composed chiefly
of the various Representatives and their families, residence in
Tangier offered no occupation for the leisure hours of a young and
active man. Thrown therefore on the resources of sport, he mingled
constantly with the wilder natives of the hills as well as with the less
uncivilised farmers and agricultural peasantry of the plains. His
interest in these folk grew, and he gained their respect and even
affection.
Justice amongst these people, when regarded from a purely
personal point of view, as Mr. Hay found, often took rather a romantic
than a strictly logical form. But his hope was to gain the hearts of the
natives, and he knew that such an aim was best attained by bending
in some cases to such national prejudices and customs as those
which are illustrated in the following letter to his mother.

‘The Wilderness,’ Tangier, June 22, 1852.


The other night A. and I were woke by my servant Azdot informing me he had
just seized a robber who had come into the garden to steal our horses, but that the
fellow, though stabbed in the breast by the son of Hadj Abdallah, whom he had
attacked with a sword, had managed to slip out of his jelab (outer cloak) and get
away, leaving as trophies the jelab and a sword they had wrested from him.
A quarter of an hour after I had dismissed Azdot, I heard a couple of shots
close by the house. My people had found the companion of the robber, who
attacked them and then attempted to make off and was fired upon, but managed to
get away—though tracks of blood were found in the gap of the hedge through
which he had escaped.
This morning I sent off a body of my hunters into the country, about twelve
miles from here, to where I suspected the robbers lived: the men were identified
and brought before me. They confessed their crime, but declared that they had
only come to rob the fruit.
Whilst telling the man the punishment I was about to inflict on him, he escaped;
so we raised a hue and cry, and judge and attendants all made after him. His
object, however, was only to get hold of my horse, whose protection he claimed,
according to Moorish custom. He was again brought before me and I was
compelled to let him off the bastinado[23], condemning him to prison only. R. was
standing near me at the time and, to his surprise, the robber sprang towards him,
and seizing him by the hand said to me, ‘I call on you in God’s name and for the
love of this boy, under the hem of whose garment I seek refuge, to have pity on
me.’
After this appeal there was no use in talking of punishing the man, and the
upshot of all was that I caused the rascal to pay a doubloon to my men and two of
the Kaid’s soldiers for arresting him. The man and his brother are the Robin Hoods
of this neighbourhood, and, grateful for my pardon, declare that they are ready to
defend me and mine whenever I call on them: or if any of my cows, camels, or
horses are robbed to cause them to be restored.
Our Governor has given an order to my people to kill any man coming into my
garden at night. This order is published: so we are safer from thieves than you are
in England. I have generally some dozen fine fellows, armed to the teeth, who
guard my garden all night, and who seek for no other compensation than to be my
friends.

The promise made by the robber was faithfully kept, and Mr. Hay
reaped the reward of his leniency in after years, as, by this clan at
least, his property was always respected.
An indefatigable sportsman, Mr. Hay delighted in expeditions into
remote districts of the country in pursuit of game. It was thus in part
that he acquired his intimate knowledge of the character of the
people. Brought into personal contact with the wild tribesmen, in
circumstances which strongly appealed to their natural chivalry, he
gained an influence among them which he was often able to turn to
useful account. A good illustration of his power of dealing with the
native races is afforded by his suppression of piracy among the
Rifians. The story is told in his own words.
Before the year 1856, vessels becalmed on the Rif coast between
the Algerian frontier and the Spanish fortress Peñon, which is
situated about sixty miles to the eastward of the Moorish port of
Tetuan, were frequently captured by Rifian ‘karebs,’ large galleys
manned by thirty or forty men, armed with long guns, pistols, and
daggers.
When a vessel becalmed, drawn by the current, approached the
Rif coast, especially in the vicinity of the village of Benibugaffer, near
Cape ‘Tres Forcas,’ about fifteen miles to the westward of the
Spanish fortress of Melilla, the natives launched their ‘karebs,’
hidden in nooks on the rocky coast, or buried under sand, and set
out in pursuit, firing volleys as they neared the vessel. The crew, if
they had not escaped in the ship’s boats when the piratical craft
hove in sight, were made prisoners, but were not in general ill-
treated unless they attempted to offer resistance.
On landing, they were compelled to labour in the fields, receiving
a daily allowance of very coarse food. The captured vessel was rifled
of cargo and rigging, and then burnt, so as to leave no vestige.
In the year 1851 a British vessel was taken by the ‘karebs’ of
Benibugaffer.
In pursuance of instructions from H.M.’s Government, a strong
representation was made by me to the Sultan of Morocco, then Mulai
Abderahman, demanding that the pirates should be chastised, that
compensation should be given to the owner of the vessel, and that
energetic steps should be taken by His Sherifian Majesty to put a
stop to these piratical acts of his lawless subjects of the Rif.
The Sultan, on the receipt of this demand, dispatched officers
from his Court to the Rif country with a Sherifian edict to the
chieftains, directing that the sums demanded for the destruction of

You might also like