How Ada was conceived: the language not the woman.
In the 1970s the United States military software was comprised with a multitude of different languages and subcategories of those languages. When such a vast and important system has hundreds of different languages, the maintenance and efficiency can be nearly impossible. Eventually the military pulled their resources, meeting with many different companies, and software teams around the world to create a list of requirements for a new high level language to be forged. After many revisions and cooperating with various people, the United States government formed the requirements for a new language to be created and they include:
Readability: The syntax had to focus on readability because the military software were expected to have a minimum lifetime of 30 years. This mean that much more effort and cost would have to be spent on the maintenance as opposed to the initial development. Readability improves the cost of maintenance.
Efficiency: the language has to be able to produce very efficient code
Provability: The language must strongly support efforts to prove the correctness of the code. Military systems controlling weapon systems MUST work correctly to avoid unintentional death and property damage.
Expressiveness- The language should provide the expressiveness, so that developers can model the problem domain clearly and directly, rather than modeling through assumptions.
After the United States government had set these requirements, a competition was made for several companies around the world to create a language to meet these strict requirements and after several rounds the winning team were from France led by Jean Ichbiah.
The team from France had named the language “Ada” after Augusta Ada Byron, Countess of Lovelace (1815-1852). Augusta was a very successful mathematician, who aided Charles Babbage with the creation of the difference engine in the early 1800s and is regarded as the world’s very first programmer since she did the programming on this difference engine.
A first look at Ada
In any programming language, there is a starting point for instance, in any C language they begin with a function called Main. Ada, however doesn’t have the same rules, instead Ada uses a procedure with no parameters. This simple program will show a lot of Ada with little code:
-- Hello World Program
Procedure Hello is
One of the first things that is noticeable is that Ada does not use curly braces unlike Java that requires curly braces for every statement. Ada does not use square brackets ( [and] ), and has sixty-nine reserve words.. The combination of Begin and End defines the body of the procedure. According to Dr. Lyle, one might also notice “that we have to include the package name before each call to a procedure defined in the package. In order to improve the readability of the source code and to reduce the amount of typing required, we can include a with command following the use command.”
Like in all other languages there are rules when naming identifiers. Ada’s rules are rather simple when it comes to naming such as:
An Identifier has to start with a letter of the alphabet.
The Identifier can be made up of as many letters, numbers and underlines as you want as long as they only occur singly, and as long as an underline is not the last character of the identifier.
Case of letters do not matter; Procedure = PRoCeDURE
There is no limit on the length of the Identifier as long as it fits on one line of text(compiler may put a length limit)
There can be no blanks or special characters can be used as part of an Identifier
Ada methods are basically subprograms that include operators and operations. Operator symbols include: =, /=, <, >, <=, >=, &, +, -, /, *. Non symbol operators are the reserved words, which include: xor, or, not, rem, ads, mod, and. More experienced Ada programmers usually use the package specs for declaring such methods, and for overriding or overloading the existing methods.
Ada Data types
Most Object-oriented programming languages have a predefined inheritance hierarchy, but yet again Ada83 did not have predefined inheritance, at least not until 1995. Ada allows you to define your own type and creates a new type as opposed to C++, which the typedefcommand only creates an alias for the type. Ada provides a lot of different types such as:
-Enumeration Types- Boolean values which only have a true or false value and character types. Enumeration types are NOT numeric types.
- Modular types- e.x.: type byte is mod 2**8; this code snippet defines an unsigned integer type named byte. The programmer must define their own modular type and all arithmetic on modular types will equal in a value within the valid range.
-Composite types- Record types are very similar to a struct in C, or a record in Pascal. It is a grouping of sort of unalike data elements into a type. In Ada, there are only two types of records, ordinary (cannot be extensible) and tagged (can be extended through inheritance) for example:
Type Inventory_Item is record
UPC_Code : String(1..20);
Description : String(1..256);
Quantity : Natural;
Unit_Cost : Float;
The above code segment is an “Ordinary” record type taken from adaic.org. The only difference between an ordinary record and a tagged record according to Jim Rogers is “the tagged record becomes the root of an inheritance hierarchy.”
Task types are implemented to define tasks with similar behavior. The task itself is a concurrent thread of execution in Ada which are also extremely similar java’s threads. Other Ada data types include fixed point types, floating point types, Scalar types, access types.
“One of the three fundamental building blocks of every computer program is iteration. In nearly every serious program there is at least one loop.”(Ada distilled 26). For loops are very simple not in just Ada, but in every language and the simplicity is that every loop requires an end loop. During Iteration, the index is a constant within that particular loop which coincides with the statement “Iteration safety is absolutely fundamental to Ada” (Ada Distilled, 26). A for loop can also be used to traverse a two dimensional array, it becomes a little more complicated because a nested loop would be required, which is a loop within a loop. For loops in Ada iterate through an explicitly stated range of discrete values. The control variable used in a for loop is only visible within the loop body and is a read-only variable within the loop body, which means that you cannot explicitly assign any value to the control variable. The programmer does NOT declare the control variable before used.
While loops are often preferred over for loops and are similar to most other while loops in other languages. A while loop is a conditional loop that starts the test at the top of the loop for example:
While condition loop
--body statements go here
If condition then
--statement(s); can also include an else statement within the If statement.
The If statement above is a conditional statement that is always evaluated with a true or false, Boolean value. In Ada the compiler will just throw a syntax error, if there happens to be an extra semicolon.
There are two kinds of subprograms, functions or procedures and there is a strong difference between the two. Procedures can be used to implement algorithms (Ada-distilled, 40). Procedures may be able to pass parameters out through their parameter list but never return a value through a return statement. The three passing modes are: IN, OUT, and IN OUT. IN parameters are treated as constants within a subprogram. OUT parameters have no reliable initial value upon entering the procedure, but are expected to be written to. IN OUT parameters have an initial value and may be written to. “Default mode is IN (adaic.org).” Example of Procedure with a passing IN OUT mode:
Procedure Swap (Left, Right : IN OUT Integer) is
Temp : Integer := Left;
Left := Right;
Right := Temp;
Functions will always return a value, unless the function raises an exception. The only mode that functions are allowed to use is the IN mode.
Object Oriented Programming can be described with five mechanisms: objects, operations, encapsulation, inheritance, and polymorphism. Objects and operations have been explained in Ada83, but in the Ada95 update that was one of the major features. Inheritance is basically a way for incrementally build new types from already existing one by modifying and added properties. You can break down Inheritance as well into derivation, overriding, and type-extension.
Derivation is used to let a new type inherit the data structure and the operations of some other type, the new type would be the child/descendant and the other type would be considered the parent. The descendant or derived type will inherit the basic operations of the parent type. You can look at www.adahome.com to view an example of this.
Although type derivation and overriding separately are very powerful tools, they aren’t capable enough to implement inheritance, because even though they provide specialization of the behavior of a type, they will not let the programmer to specialize the data structure of that type. Type extension is a good tool that is used to add parts to the data structure and is directly linked to type derivation because the extended type is a new type that is created by derivation of an already existing type. Tagged types are also called Extensible types. Tagged means that every object of a tagged type will carry a tag that identifies its type. An example from adahome.com of a tagged type declaration:
Type Person is tagged
First_Name: String (1...4);
type Man is new Person with
Bearded: Boolean := False;
Type Woman is new Person with
“In this example, both types Man and Woman are derived from Person. They both inherit from Person. Man extends Person by adding a new component, Bearded. Woman adds no new component to its parent type; notice the syntax “with null record” used for this purpose. Person, Man and Woman are all tagged types.”(Adahome.com (4.2)).
Polymorphism in Ada. When the compiler processes a function call such as Put (Stuff2), the call to Put() is bound to Put(Stuff_Type), because that is the only available definition. Within procedure Put(), the operations Name(), Call(), and Type_Name() are invoked, but it depends on the type of object received. “Polymorphic behavior must be elicited within a parameterized procedure, and if the parameter for which polymorphic behavior is required is of type T, then it must be declared with the type T class. Ada thus triggers polymorphic behavior through modification of a parameter declaration, rather than through modification of a subprogram like C++.”(cs.Calvin.edu)
Exceptions handling is the process of responding to the occurrence, during computation. In Ada, there are five predefined exceptions which are:
“CONSTRAINT_ERROR exception is raised when an attempt is made to violate a range constraint.” For example if you have a procedure that has an integer range from 1..20 and the programmer enters a number outside of that range then the constraint exception will occur. The exception Handler is placed at the end of a block statement, or body of a subprogram or task/generic units. For example:
x:integer range 1..29;
put("please enter a number ");
when constraint_error =>
put("that number should be between 1 and 29");
when others =>
put("some other error occurred");
Now when the user enters a number between 1-29, no error will occur and the message “Thanks!” will appear. If not, then the error message “that number…” should show up.
“-In Ada83, NUMERIC_ERROR was raised when a numeric operation cannot deliver a correct result, but in the Ada95 update it was redefined to be the same as a CONSTRAINT_ERROR.
-PROGRAM_ERROR is raised whenever the end of a function is reached which means that no return statement was encountered, and can also be raised whenever an elaboration check fails.
-STORAGE_ERROR is raised when you have no more space, whether it be during a call to create a dynamic object or when calling a sub-procedure and stack space is exhausted.
-TASKING_ERROR is thrown when exceptions arise during intertask communication, for example: when a task attempts to rendezvous with a task that has aborted.”
If the exception that was raised in the subprogram isn’t handled, the exception is propagated to the sub-procedure that called it. Then a handler is searched for the exception and if not found again then the process is repeated until the handler is found or the task is aborted. One of ada’s features is having the ability to define your own exceptions, they can be placed wherever a normal declaration is put.
There are two models Ada supports for concurrency: multitasking and distributed objects. Tasking is implemented using standard Ada language syntax (Ada: distilled, 87). Each task is a sequential entity that may operate concurrently with, and communicate with, other tasks. A task object may be either anonymous or an object of a task type.
According to the author of Ada-Distilled, “Tasks are concurrent active objects and once a task is created and activated, the task is only in one of two states: executing or suspended. Tasks may also be created so they “talk” with other task(s). The way they communicate between each other is by placing requests for rendezvous in the entry queue of the called task. Then the calling task goes into a suspended state until the entry in the queue is consumed and processed by the called task.”
Readability was one of the major requirements if not the most important requirement when Ada was in development. The language was designed to support the construction of a long-term and highly reliable software systems. Ada does it’s best to give a high productivity rate and a low bug rate. I like that Ada makes concurrency a part of the language unlike java exposing threads through a library. I think that the no braces feature is really nice because less typing, but the programmers really have to be organized when structuring their code. The with and use commands are great because the programmer will know exactly what packages they are going to be using unlike in my experience with Java and C#, the programmer has to call on so many libraries and you don’t know if you are going to use that library or not and the libraries seem a bit hefty.
In Ada you can really express and recognize your own design. I find that using the GNAT compiler with Ada has a good memory/speed ratio, doesn’t really bog down compared to some of the older compilers I’ve read about. Another problem that I see is getting confused when naming the identifiers or objects, since Ada has no predefined inheritance, but at the same time that’s great because you can be really descriptive on your data types and identifiers, so when reading the source code you know exactly what is what and you design something truly unique. Here is an example to show the readability of an Ada program:
With Ada.Text_Io; use Ada.Text_Io;
Package body Operator_examples is
Procedure Print_Message(For_Day : in Days) is
If For_Day in Saturday..Sunday then
Put_line(“Go to Work!”);
I think that the ease of writing Ada programs really depends on the depth of which you want to go. It can be really easy to create Ada programs because of no braces and the freedom of creating your own data types and the way Ada lets you name your identifiers. Even if you don’t know Ada, but know other languages such as java you will be able to pick it up and write code very quickly because the conditional statements and control structures are extremely similar with most other languages with the exception of few things Ada does and does not do(which are usually easy to figure out). I think that Ada’s concurrency is its strongest feature, because of the real-time programming.
Asynchronous task interactions are supported, such as timeouts and task termination. A really good feature that was added in the Ada 95 update was the OOP support. Ada’s tagged typed facility features classes, polymorphism, inheritance, and dynamic binding. In Ada 2005, features were added for OOP such as interfaces similar to Java which was amazing and a lot easier to write OOP code in Ada.
I think that Ada is a very reliable high-level programming language, for the more obvious reason that it was built for the Department of Defense, and the requirements that had to be met. Errors such as pointers as integers are prevented and Ada’s array boundaries checking prevents buffer overrun that are common in C and C++. One downfall to the language is the flexibility which can help not meet particular certification requirements, but Ada bounces back with a compiler directive, and pragma Restrictions that lets the programmer “restrict the language features to a well-defined subset.”(adacore.com). NASA uses Ada based applications, which they use to take advantage the feature of existing software and its real-time functionality.
The biggest thing that sets Ada apart from any other language is the High-Integrity domain and high level, well-defined concurrency support unlike C or C++ which has no concurrency support and Java which is very error prone even at a low level. If major institutions such as the United States government or NASA uses and has used Ada Since 1983, that itself says a lot on the reliability of this language.
Well since the birth of Ada, the programming language would cut the cost of software and engineers/specialists down in the long run, because the software that was used by the United States government was comprised of multiple languages. With all these languages, you needed to have programmers that knew these languages and could offer support, which was a lot. Now that one language is being used, you only need programmers that know that one languages so therefore you don’t need as many. The flip side of that was since it was a new language, you needed to train new people. The cost of writing the programs in multiple languages was cut down to one language, but since it was new and depending on the complexity of the program that needed to be written went with the experience of the programmers. Designing Ada was driven by the need to lower the costs of software.
The cost of executing programs written in Ada was greatly influenced by the writability of the code, and since Ada had such strong type checking before run-time made the execution much more efficient. The cost of Maintainability was a big deal as well, since in the 80’s there was no language that had good support. The evolution of Ada over the years has increased support for safety-critical systems and high-security applications mainly for military usage such as weapon systems. Ada2012 new tasking features lets the programmer “express common real-time idioms (periodic tasks, event-driven tasks), and the Real- Time annex provides several facilities that allow you to avoid unbounded priority inversions.”(Adacore.com). All in all I think that Ada, is one of the top dogs out there even after 31 years of being around when It comes to writability and reliability, and cost. Ada was founded on the basis of those principles.
"Object-Oriented Programming with Ada 9X." Object-Oriented Programming with Ada 9X. N.p., n.d. Web. 04 Nov. 2014.
"AdaCore." The Ada Programming Language. N.p., n.d. Web. 04 Nov. 2014.
"Safe and Secure Object-oriented Programming with Ada 2012's Contracts." Embedded. N.p., n.d. Web. 04 Nov. 2014.