Oh Yes! Ada Now!
I hope to provide some useful information about programming in Ada, if you are interested. For more introductory material, have a look at the AdaCore learning site.
I have written a quick introduction to Ada for developers who are familiar with Rust: Getting Started With Ada by Way of Rust.
My Road to Ada
I first learned about Ada while studying computer science in the late 1980s. At that time it was definitely not very accessible for hobbyists or even students, and I don't remember ever writing or compiling actual Ada code, even if there may have been a compiler available at the university. The lecture notes on many programming courses had examples in Ada, though, even if the practical adopted language was Modula-2 (logically following from Pascal).
Ada seemed like a fairly complex but still comprehensible language, and indeed one of the points emphasised about was the readability. Object-oriented programming was just getting started big time just as the 1990s began, but at that time Ada did not have any of those capabilities—that came only with Ada 95. What Ada did have at the start, of course, was encapsulation with packages.
There was a backlash against Ada in the 1980s and 1990s, and in retrospect it seems that much of it was misguided. Because the language was commissioned and mandated by the United States Department of Defense (DoD), Ada was mistakenly derided as a language "designed by committee", when the actual origin story was nothing like that.
I had absolutely nothing to do with Ada before the year 2022. Of course I had been thinking about it from time to time
as I used various programming languages. I think I was ultimately driven to use Ada because of my desire to be
able to build data types that dealt with ranges of valid values. In an object-oriented language it is relatively
easy to implement a class that wraps a primitive type like an int
and controls access so that you
can't set the wrapped value to anything else than what is allowed. For example, you could have a volume setting (in an
audio context) that could only get the values from 0 to 99 inclusive. However, that is going to lead to a lot of
code duplication unless you use inheritance.
I remembered that just like Pascal and Modula-2, Ada had subrange types that could give you both compile-time and run-time checking of values. In Ada it is possible to create new data types like:
type MIDI_Note_Type is range 0 .. 127; type MIDI_Channel_Type is range 1 .. 16;
You would not be able to mix these types together without explicit conversions, and sometimes even those are clearly wrong semantically, but you can rely on the compiler to stop the nonsense right away. However, subrange types are definitely not the only reason to use Ada.
Because I had some projects that required lots of types like this, I started to investigate the state of Ada, and I found that there seems to be some rekindled interest in it. There is also a connection between Rust and Ada, because both languages are concerned with safety, and there has been some cooperation between eminent companies (AdaCore and Ferrous Systems).
I started to learn Ada for real, using primarily two sources:
- learn.adacore.com
- Programming in Ada 2012 by John Barnes (Cambridge University Press)
Both are excellent resources, but they do reflect the size of the language both in breadth and depth.
The story of the name
The Ada programming language was named after Ada Lovelace, considered by many to be the first programmer in the world, working on Charles Babbage's computational engines.
Why is this section of the website called Oh Yes! Ada Now!? Well, in my early days of programming in Pascal I learned a lot from the book Oh! Pascal! by Doug Cooper. He is an excellent educator who also wrote a similar book about Modula-2, called Oh My! Modula-2!—you can see a pattern in the names. In the preface of the latter book Doug Cooper writes:
Let me begin with a confession: when I began to write, I wondered if yet another introductory programming book on yet another general purpose language was needed. Nevertheless, thought I, better Oh My! Modula-2! today than Oh No! Not Ada! tomorrow.
I have always thought that this was unnecessary dig at Ada, perhaps more borne out of the general sentiment at the time (the book was published in 1990) than the actual merits of Ada against Modula-2 and other general purpose languages. However, this was small potatoes compared to (but perhaps affected by) Sir Tony Hoare's Turing Award lecture in 1980, where he basically pleaded not to allow any critical software to be written in Ada. It boggles the mind.
As it happens, today Modula-2 is nearly nowhere to be seen, while Ada has successfully been used in avionics, air traffic control, railroad systems, medical devices, banking, military and space technology. Whoops! And I actually liked Modula-2, even better than the later language designs by Niklaus Wirth, but it turns out that I like Ada even more than Modula-2. (I used to write a lot of Modula-2 software in the late 1980s using the TopSpeed Modula-2 compiler and IDE.)
This is why, in direct reference to Doug Cooper's preface to his Modula-2 book, I am calling this section of the site Oh Yes! Ada Now!.
Some notes on the nature of Ada
In this section I have collected some of my notes about why Ada seems to me like a programming language that deserves more credit and exposure than it has been getting. Some of those things are personal and somewhat subjective, while some are more general observations on the features of programming languages.
The syntax of Ada
For someone who has learned to program in the style of the C family of languages (C, C++, Java, C#, JavaScript) Ada may seem a little backwards, but it actually belongs in the Pascal, or maybe I should say ALGOL family. The differences are most obvious in parameter lists for subprograms.
In Ada, parameters to subprograms are listed name first, type second:
procedure Greet (Name : String) is Ada.Text_IO.Put_Line ("Hello, " & Name & "!"); end Greet;
Also, procedures and functions are different entities. Procedures don't have a return type, while functions
do. This is, of course, different from the C family, where even procedures are "functions", but they "return"
void
. You can get used to that over time, but the Ada way makes more sense, to me at least.
A function in Ada looks like this:
function Square (N : Integer) return Integer is begin return N * N; end Square;
There are very few "special" characters used in Ada. I've been told by a seasoned Ada developer that this originally was because the various keyboards on the many terminals at the time made it difficult to produce characters like curly brackets and square brackets. In Ada, parts of a program are not separated by curly brackets, and even array elements are accessed with normal parentheses.
As seen from the examples above, procedures and functions are delimited by the begin
and end
keywords.
Persistence of vision
The core of Ada has changed very little since the first published standard, Ada 83. Since the definition of Ada is an international standard, the change process is necessarily slower than research projects or industry efforts.
It has been amazing to note that almost from the beginning Ada had ideas that are only recently started to appear in other programming languages. Not all of them, but very many of them. This has prompted me to formulate this:
Every ambitious programming language is asymptotically approaching Ada.
Modular programming and information hiding with packages? Yes. Abstract data types? Generic types?
Object-oriented programming? Yes. Also, sensible
enumerated types, variant records (akin to sum types), no implicit conversions between data types, and more.
Even if
and case
expressions appeared in Ada 2012. Pattern matching is not there
yet, but it seems to be on its way.
Broad spectrum
Ada covers a very wide spectrum of computing. On one hand, you can design and describe things on a very high level using packages and generic types, but on the other hand you can specify the exact machine representation of a data structure for low-level purposes.
In the context C++ (and now also with Rust) you can read a lot about "zero-cost abstractions". Well, you don't get to read that about Ada, but that doesn't mean they don't exist. The Ada compiler obviously does a lot of work to translate high-level concepts to efficient machine code. In fact, the Ada compiler is one of the most important tools in your Ada toolkit, given that it also needs to pass a verification suite to ensure it implements the standard.