by Jim Rogers

This is part three (of five) of this article. Click here to return to part two, or click here to go to the article’s table of contents.

Ada Operators

Operator Java C/C++ Ada
Assignment = = :=
Equality == == =
NonEquality != != /=
Greater Than > > >
Less Than < < <
Greater Than Or Equal >= >= >=
Less Than Or Equal <= <= <=
PlusEquals += +=  
SubtractEquals -= -=  
MultiplyEquals *= *=  
DivisionEquals /= /=  
OrEquals |= |=  
AndEquals &= &=  
Modulus % % mod
Remainder     rem
AbsoluteValue     abs
Exponentiation     **
Range     ..
Membership instanceof   in
Logical And && && and
Logical Or || || or
Logical Not ! ! not
Bitwise And & & and
Bitwise Or | | or
Bitwise Exclusive Or ^ ^ xor
Bitwise Not ~ ~ not
String Concatenation +   &

C++ allows extensive overloading of operators. Ada allows a limited overloading of operators. The exception in Ada is that the assignment operator ( := ) cannot be overridden. When you override the equality operator (= ) you also implicitly override the inequality operator ( /= ). Java does not allow overriding of operators.

If you want to achieve the equivalent of overriding the assignment operator in Ada you must declare your type to inherit from the abstract tagged type Controlled defined in the package Ada.Finalization. Controlled types provide three operations that can be overridden.

  • Initialize is called during object construction and allows control over the initialization logic for the controlled type. The Initialize procedure performs much the same function as a default constructor in C++ or Java.
  • Adjust is a procedure that is called at the end of assignment. Overriding Adjust lets you control assignment behavior.
  • Finalize is called when an object goes out of scope. The Finalize procedure can be overridden to achieve the same purposes as a C++ destructor.

Ada also allows the definition of limited types. Any type declared limited has no predefined operators, including assignment. Use of limited types allows the programer to selectively restrict the available operations on a type. Only those operations specifically provided by the programmer will be available for a limited type.

The package Ada.Finalization defines a second abstract tagged type named Limited_Controlled. Limited_Controlled types do not have an adjust procedure.

Any attempt to assign a value to an object of a limited type will result in a compile time error message.

Operator Examples

This example is divided into three files. The first file is a package specification. This package specification defines two types and the subprograms for those types.

The Days type is an enumeration type containing the names of the days of the week in English. Days has the procedure Print_Message defined for it.

The Daily_Sales type is an array of floats indexed by the values in type Days. Daily_Sales has two functions defined for it: Total and Geometric_Mean.

The package Operator_Examples becomes visible to another compilation unit when that compilation unit names  Operator_Examples in a  with clause. Java does not require this explicit declaration of dependency. Instead, the compiler must scan every line of code to determine external dependencies. The public contents of this package specification become directly visible to a foreign compilation unit when it follows the with clause with a use clause. The Ada use clause is similar to a Java import statement. 

-- Ada operator examples
package Operator_Examples is
   type Days is (Monday, Tuesday, Wednesday, Thursday, Friday,
      Saturday, Sunday);
   procedure Print_Message(For_Day : in Days);

   type Daily_Sales is array(Days) of Float;
   function Total(Sales : in Daily_Sales) return Float;
   function Geometric_Mean(Sales : in Daily_Sales)
       return Float;
end Operator_Examples;

The next file is the package body, or implementation. The package body contains the definitions of all the subprograms declared in the package specification. In this example the package body also declares a dependency upon two packages: Ada.Text_Io and Ada.Numerics.Elementary_Functions . As you can see above, the exponentiation operation is defined as ** . The normal version of this operator takes an integer value as its power. I wanted to pass it a fractional value. I declared a dependency upon Ada.Numerics.Elementary_Functions and then included the same package in a use clause so that I could use the overloaded version of the exponentiation operator that takes a float for the exponent value.

with Ada.Text_Io; use Ada.Text_Io;
with Ada.Numerics.Elementary_Functions;
use Ada.Numerics.Elementary_Functions;

package body Operator_Examples is
   procedure Print_Message(For_Day : in Days) is
      if For_Day in Saturday..Sunday then
         Put_Line("Go Fishing!");
         Put_Line("Go To Work!");
      end if;
   end Print_Message;

   function Total(Sales : in Daily_Sales) return Float is
      Sum : Float := 0.0;
      for I in Sales'range loop
         Sum := Sum + Sales(I);
      end loop;
      return Sum;
   end Total;

   function Geometric_Mean(Sales : in Daily_Sales)
      return Float is
      Product : Float := 1.0;
      for I in Sales'range loop
         Product := Product * Sales(I);
      end loop;
      return Product**(1.0 / Float(Sales'Length));
   end Geometric_Mean;
end Operator_Examples;

The third file contains the parameterless procedure used as the starting point for a program to exercise the Operator_Examples package. This package declares a dependency upon two different I/O packages. The package Ada.Text_Io defines text file operations and procedures for the input and output of strings and characters. The package Ada.Float_Text_Io defines text file input and output procedures for the type float. Both packages have Put procedures. The package Ada.Float_Text_Io overloads the Put operations defined in Ada.Text_Io.

-- The driver procedure to exercise the
-- Operator_Examples package.
with Ada.Text_Io; use Ada.Text_Io;
with Ada.Float_Text_Io; use Ada.Float_Text_Io;
with Operator_Examples; use Operator_Examples;

procedure Operator_Exerciser is 
   My_Sales : Daily_Sales;  
   My_Sales(Monday) := 1234.56;
   My_Sales(Tuesday) := 1342.65;
   My_Sales(Wednesday) := 1432.55;
   My_Sales(Thursday) := 1332.44;
   My_Sales(Friday) := 2345.67;
   My_Sales(Saturday) := 2222.00;
   My_Sales(Sunday) := 1232.33;

   for Day in Days loop
      Put(Days'Image(Day) & ": ");
   end loop;
   Put("Total sales: ");
   Put(Item => Total(My_Sales), Aft => 2, Exp => 0);
   Put("Mean Sales: ");
   Put(Item => Geometric_Mean(My_Sales), Aft => 3, Exp => 0);
end Operator_Exerciser;

The output from this program is:

MONDAY: Go To Work!
TUESDAY: Go To Work!
FRIDAY: Go To Work!
SATURDAY: Go Fishing!
SUNDAY: Go Fishing!
Total sales: 11142.20
Mean Sales: 1537.634

This ends part three of this article. Click here to continue with part four, Loops and other control structures.

Share and Enjoy:
  • email
  • LinkedIn
  • Twitter
  • Facebook
  • Digg
  • RSS