Ada

Appeared in:
1983
Influenced by:
Paradigm:
Typing discipline:
File extensions:
.adb, .ads, .ada
Versions and implementations (Collapse all | Expand all):
Programming language

Ada is a powerful modular general-purpose programming language, meant for development of reliable mission-critical software.

Ada was developed in 1979-80 as a project by US Department of Defense. The intent of the project was to reduce the number of various languages in use (by 1983 there were over 450 languages used for different projects) by developing a new language. High Order Language Working Group (HOLWG) started with creation of a list of requirements a high-level programming language should meet. They were known as Steelman language requirements and emphasized reliability, maintainability and efficiency. Among other features, they included exception handling, run-time errors check and concurrent computations.

After the requirements were ready, the existing languages were reviewed and analyzed; none of them satisfied the requirements. Several teams competed to develop a new language; the winner was Jean Ichbiah from CII Honeywell Bull team. In 1979-80 the reference manual of the new language named Ada was finalized and approved by DoD. It was based on Pascal and borrowed some elements from ALGOL. The first compiler that passed validation was NYU Ada/Ed translator (certified in 1983) which later evolved into GNAT.

The first standard of the language, later referred to as Ada 83, was accepted in 1983 as ANSI/MIL-STD 1815A and in 1987 as ISO-8652:1987. The second one, Ada 95, was accepted as ISO-8652:1995; with it Ada became the first ISO-standardized object-oriented language. Besides, the language was extended to become applicable to numeric, financial and systems programming.

Language features:

  • strong typing. There are no untyped objects in the language, and data conversions have to be explicit.
  • modularity mechanism includes three types of program units: tasks (units of concurrent execution), packages (modularity units, used, for example, for implementing abstract data types) and procedures.
  • a rich set of tools for error checks and exception handling, both at compile-time and at run-time. The language focuses on detecting as many errors as possible at compile-time. Compiler error messages are made to provide as much information as possible.
  • dynamic memory management has no generic pointers, but rather explicitly declared access types. The language semantics allow to do automatic garbage collection, but most implementation don’t have this feature.
  • one of the key requirements was readability of the code, even though it hurt ease of coding. As a result, the syntax is a bit overweight: keywords and operators (except for math) use English words without abbreviations.
  • support for generic programming, which was not included in the Steelman requirements.
  • support for concurrent programming, based on rendezvous mechanism.

Nowadays there exist hundreds of Ada implementations for virtually every operating system, plus compilers to Java and .NET bytecode. It is still widely used in USA and Europe when developing large-scale mission-critical applications (which are not limited to army purposes).

Elements of syntax:

Inline comments --
Case-sensitivity no
Variable identifier regexp [a-zA-Z](_?[a-zA-Z0-9])*
Variable assignment :=
Variable declaration variable: type
Grouping expressions ( ... )
Block begin ... end or foo ... end foo (foo in { if, do, ... })
Deep equality =
Deep inequality /=
Comparison < > <= >=
Function definition function f(p1 : type1; p2 : type2; ... ) return returntype is begin ... end f;
Function call f(a, b, ...)
Function call with no parameters f
Sequence ;
If - then if condition then ... end if
If - then - else if condition1 then ... elsif condition2 then ... else ... end if
Loop forever loop ... end loop
While condition do while condition loop ... end loop
Do until condition loop ... exit when condition end loop
For each value in a numeric range, 1 increment for i in 1 .. 10 loop ... end loop
For each value in a numeric range, 1 decrement for i in reverse 1 .. 10 loop ... end loop

Examples:

Hello, World!:

Example for versions gnat 3.4.5, gnat 4.3.2
with Ada.Text_IO; 
 
procedure HelloWorld is
begin
  Ada.Text_IO.Put_Line("Hello, World!");
end HelloWorld;

Factorial:

Example for versions gnat 3.4.5, gnat 4.3.2

This example uses recursive factorial definition.

Note that there are different packages for printing text, integers and long integers. put command generally accepts several arguments: Item is the number/string to print, Width is the number of positions to use, Fore and Aft are the numbers of decimal digits to be printed before and after decimal separator etc. If there is only one argument, it is considered to be Item. Setting Width to a number which is less than the actual length of the number prints it without leading spaces (which is the default for Ada).

Another thing to note is that Ada doesn’t support implicit data type conversions, so to calculate N*Fact(N-1) one has to convert N to Long_Long_Integer explicitly first.

with Ada.Text_IO, Ada.Integer_Text_IO, Ada.Long_Long_Integer_Text_IO;

procedure Factorial is
begin
   declare 
      function Fact (N: Integer) return Long_Long_Integer is
      begin
         if N=0 then
            return 1;
         else 
            return Long_Long_Integer(N)*Fact(N-1);
         end if;
      end Fact;
   i: Integer := 0;
   begin
      loop
         Ada.Integer_Text_IO.Put (Item => i, Width => 1);
         Ada.Text_IO.Put ("! = ");
         Ada.Long_Long_Integer_Text_IO.Put (Item => Fact(i), Width => 1);
         Ada.Text_IO.New_Line;
         i := i + 1;
         exit when i=17;
      end loop;
   end;
end Factorial;

Fibonacci numbers:

Example for versions gnat 3.4.5, gnat 4.3.2

This example uses recursive definition of Fibonacci numbers.

with Ada.Text_IO, Ada.Integer_Text_IO;

procedure Fibonacci is
begin
   declare 
      function Fib (N: Integer) return Integer is
      begin
         if N<3 then
            return 1;
         else 
            return Fib(N-1) + Fib(N-2);
         end if;
      end Fib;
   i: Integer := 1;
   begin
      loop
         Ada.Integer_Text_IO.Put (Item => Fib(i), Width => 1);
         Ada.Text_IO.Put (", ");
         i := i + 1;
         exit when i=17;
      end loop;
      Ada.Text_IO.Put ("...");
   end;
end Fibonacci;

Quadratic equation:

Example for versions gnat 3.4.5, gnat 4.3.2

Ada provides complex datatype, which requires using packages Generic_Complex_Types and Generic_Complex_Elementary_Functions and instantiating them with the type of complex number to use (in this case — floating-point numbers). Ada doesn’t support implicit data type conversions, so all casts are done explicitly.

with Ada.Text_IO, 
     Ada.Integer_Text_IO,
     Ada.Float_Text_IO,
     Ada.Numerics.Elementary_Functions,
     Ada.Text_IO.Complex_IO, 
     Ada.Numerics.Generic_Complex_Types,
     Ada.Numerics.Generic_Complex_Elementary_Functions;
use Ada.Text_IO, Ada.Integer_Text_IO, Ada.Float_Text_IO;

procedure QuadraticEquation is
    package Complex_Types is new Ada.Numerics.Generic_Complex_Types (Float);
    package Complex_Functions is new Ada.Numerics.Generic_Complex_Elementary_Functions(Complex_Types);
    package Complex_IO is new Ada.Text_IO.Complex_IO (Complex_Types);

    use Complex_Types, Complex_Functions, Complex_IO;

    A,B,C,D: Integer;
    A2f, Bf, S: Float;
    Dc: Complex;
begin
    Put("A = ");
    Get(Item => A);
    if A = 0 then
        Put_Line("Not a quadratic equation.");
        return;
    end if;
    Put("B = ");
    Get(B);
    Put("C = ");
    Get(C);
    A2f := Float(2*A);
    Bf := Float(B);

    D := B*B-4*A*C;
    if D = 0 then
        Put("x = ");
        Put(-Bf/A2f);
    elsif D > 0 then
        S := Ada.Numerics.Elementary_Functions.Sqrt(Float(D));
        Put("x1 = ");
        Put((-Bf+S)/A2f);
        Put_Line("");
        Put("x2 = ");
        Put((-Bf-S)/A2f);
    else
        Dc := Compose_From_Cartesian (Re => Float(D), Im => 0.0);
        Put("x1 = ");
        Put((-Bf+Complex_Functions.Sqrt(Dc))/A2f);
        Put_Line("");
        Put("x2 = ");
        Put((-Bf-Complex_Functions.Sqrt(Dc))/A2f);
    end if;
end QuadraticEquation;

CamelCase:

Example for versions gnat 3.4.5, gnat 4.3.2
with Ada.Text_IO,
     Ada.Characters.Handling; 
 use Ada.Text_IO,
     Ada.Characters.Handling;

procedure CamelCase is
   Text: String(1..100);
   Length: Natural;
   Was_Space: Boolean := True;
   I: Integer := 1;
begin
   Get_Line(Text, Length);
   Text := To_Lower(Text);
   loop
      if Character'Pos(Text(I)) > 96 and Character'Pos(Text(I)) < 123 then
         if Was_Space then
            Put(To_Upper(Text(I)));
         else
            Put(Text(I));
         end if;
         Was_Space := False;
      else
         Was_Space := True;
      end if;
      I := I + 1; 
      exit when I > Length;
   end loop;
end;