Language Basics

Basic:
    with Ada.Text_IO;

    procedure Hello_World is
    begin
       Ada.Text_IO.Put("Hello World!");
    end Hello_World;
Use:
    with Ada.Text_IO;   use  Ada.Text_IO;

    [...]

        Put("Hello World!");

Good Ideas in Ada

Quiz:
    double foo;

    foo = 1 / 3;
Code:
    int year, month, day, hour, minute, second;
Error:
    day = minute;
Ada strong typing:
    subtype Year_Type    is Integer range 1582..4000;
    subtype Month_Type   is Integer range 1..12;
    subtype Day_Type     is Integer range 1..31;
    subtype Hour_Type    is Integer range 0..23;
    subtype Minute_Type  is Integer range 0..59;
    subtype Second_Type  is Integer range 0..59;

    Year   : Year_Type   := 2001;
    Month  : Month_Type  := 9;
    Day    : Day_Type    := 19;
    Hour   : Hour_Type   := 12;
    Minute : Minute_Type := 0;
    Second : Second_Type := 0;
Conversion:
    day := Day_Type(Minute);
Exception handling:
with Ada.Text_IO;                       use Ada.Text_IO;
with Ada.Float_Text_IO;                 use Ada.Float_Text_IO;
with Ada.Command_Line;                  use Ada.Command_Line;
with Ada.Numerics;                      use Ada.Numerics;
with Ada.Numerics.Elementary_Functions; use Ada.Numerics.Elementary_Functions;

procedure Square_Root is

begin
   if Argument_Count < 1 then
      Put("Usage: ");
      Put(Command_Name);
      Put(" decimal");
      Set_Exit_Status(Failure);
   else
      Put( Item => Sqrt(Float'Value(Argument(1))), Exp => 0);
      Set_Exit_Status(Success);
   end if;
exception
   when Constraint_Error =>
      Put(Command_Name);
      Put(": cannot interpret numerical value from """);
      Put(Argument(1));
      Put("""");
      Set_Exit_Status(Failure);
   when Argument_Error =>
      Put(Command_Name);
      Put(": cannot take square root of ");
      Put(Argument(1));
      Set_Exit_Status(Failure);
end Square_Root;
C++ try/catch
   try {
       if (atof(argv[1]) < 0)
           throw 1;
       cout << sqrt(argv[1]);
   }
   catch (int e) {
       if (e == 1)
           cout << "square root of a negative\n";
   }
C++ Default Values
    int Tax_Amount(int income; int exemptions = 1; bool blind = false;)
    Tax_Amount(10);        // okay
    Tax_Amount(10, 2);     // okay
    Tax_Amount(10, true);  // illegal
Similar:
    function Tax_Amount (Income     : Integer;
                         Exemptions : Integer := 1;
                         Blind      : Boolean := False;) is [...]
And then call it like this:
    foo := Tax_Amount(Income => 10, Blind => True);
And, if you name the parameters, you can put them in any order at all:
    foo := Tax_Amount(Blind => True, Income => 10);
Curses: C/C++:
    move(y,x);
    addch(c);
    mvaddch(y, x, c);
    mvwaddch(win, y, x, c);
Ada overloading and defaults:
   procedure Add (Win : in Window := Standard_Window;
                  Ch  : in Character)
   is
and
   procedure Add (Win    : in Window := Standard_Window;
                  Line   : in Line_Position;
                  Column : in Column_Position;
                  Ch     : in Character)
   is
Calling with names:
    Add(Column => 0, Line => 2, Ch => 'b');
    mvaddch(0, 2, 'b');
Three common errors: Null loops:
    while (c > 0);
       c--;
Explicitly in Ada:
    while c > 0 loop
        null;
    end loop;
Dangling Else:
    if (a > b)                     if a > b then
        if (c > d)                      if c > d then
            foo = 0;                        foo := 0;
    else                                end if;
        foo = 1;                   else
                                        foo := 1;
                                   end if;
Assignment in a condition:
    if (a = 1)
        b = -1;
In Java:
    if (a = true)
        b = -1;
In Ada, it's an error:
    if a := true then
        b = -1;
Convenience:
    while (X = numleft()) {
        cout << X << " left to work on" << endl;
        process_one();
    }
Ada version if right:
    loop                                  x := NumLeft;
        X := NumLeft;                     while x > 0 loop
        exit when X = 0;                     put(X);
        put(X);                              put(" left to work on");
        put(" left to work on");             new_line;
        new_line;                            process_one;
        process_one;                         x := NumLeft;
    end loop;                             end loop;
Ada version if wrong:
    loop                                  while x = NumLeft loop
        exit when X /= NumLeft;              put(X);
        put(X);                              put(" left to work on");
        put(" left to work on");             new_line;
        new_line;                            process_one;
        process_one;                      end loop;    
    end loop;
Case and Fallthrough:
    switch (b) {                      case b is
       case 'a': do_this(); break;       when 'a' => do_this;
       case 'b': do_that(); break;       when 'b' => do_that;
    }                                    when others => null;
                                      end case;
Special syntax for multiple cases:
    switch(b) {                 case b is
        case 'A':                  when 'A' | 'a' => do_this;
        case 'a':                  when 'B' | 'b' => do_that;
            do_this();             when others => null;
            break;              end case;
        case 'B':
        case 'b':
            do_that();
            break;
    }
Templates / Generics
#include <iostream>             with Ada.Integer_Text_IO;
using namespace std;               use  Ada.Integer_Text_IO

template <class T>              procedure Generic_Swap is
void exchange ( T & x, T & y ) {      generic
  T z = x;                               type Item is private;
  x = y;                              procedure Exchange(X, Y: in out Item);
  y = z;                              procedure Exchange(X, Y: in out Item) is
}                                        Temp: Item;
                                      begin
int main ( ) {                           Temp := X;
  int a = 5, b = 10;                     X := Y;
                                         Y := Temp;
  exchange ( a, b );                  end;
  cout << a << " " << b << endl;
                                      A, B : Integer;
  return 0;                           procedure Swap is new Exchange(integer);
}                                  begin
                                      A := 1;
                                      B := 2;
                                      Swap(A,B);
                                      put(A); put(" "); put(B); new_line;
                                   end Generic_Swap;
Unset out parameters:
    procedure Foo (x: in integer; y: out integer) is
       z: integer;
    begin
       z := x + y;
    end foo;

    [...]

    bar := 2;
    foo(1, bar);
Can't use in parameter:
    procedure Foo (x: in integer; y: out integer) is
    begin
       X := 2;
    end foo;

Built-In Features

    Float'Succ(Coolant_Temp);
Numerical type attributes:
    'Succ
    'Pred
    'Value
    'Image
    'Min
    'Max
Programmer defined:
    type Tone_Type is (Low_Do, Re, Me, Fa, So, La, Ti, High_Do);
    Tone : Tone_Type;

    [...]

    Ada.Text_IO.Put (Tone_Type'Image(Tone)); -- Print as string

    Tone := Tone_Type'Succ(Tone);            -- up one note
Precise variables specifications:
     type Measurement_Type is delta 0.0000000001 digits 20;

Ada Problems

Incorrect string assignment if different length:
    Name := "Bob";
Bounded Strings:
    with Ada.Strings.Bounded;
    use  Ada.Strings.Bounded;
    package Bounded_80 is
        new Generic_Bounded_Length(80);
    use Bounded_80;
    B : Bounded_String;

    B := To_Bounded_String("Bob");

    Text_IO.Put_Line( To_String(B) );
Unbounded string:
    with Ada.Strings.Unbounded;
    use  Ada.Strings.Unbounded;

    U : Unbounded_String;

    U := To_Unbounded_String("Bob");
    Text_IO.Put_Line( To_String(U) );
You can dodge some this by using `rename':
    function To_U_Str (Source: String) return Unbounded_String
       renames Ada.Strings.Unbounded.To_Unbounded_String;

    function Reg_Str (Source: Unbounded_String) return String
       renames Ada.Strings.Unbounded.To_String;

    [...]

    U := To_U_Str("Bob");