This 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 manycore 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 welldefined 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
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:
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 nonstatic 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)
Preface
Welcome to this updated version of Programming in Ada 2012 which describes 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
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.
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 proofreading 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.
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.
An Overview
This 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.
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.
1 Introduction
1.1Standard development
1.2Software engineering
1.3Evolution and abstraction
A1.4Structure and objectives of this book
1.5References
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.1Standard development
Ada 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!
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.2Software engineering
It 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.
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