with Big_Bang;  -- This package is taboo for all times!

package Universe is

  -- Non-derivable definitions:

  PI: constant := Big_Bang.PI;

  Illegal_Argument: exception renames Big_Bang.Illegal_Argument;

  -- Types with mathematics:

  type    SI_Unit          is new Big_Bang.Primeval_Float;
  subtype Meter            is     SI_Unit;
  subtype Second           is     SI_Unit;
  subtype Meter_Per_Second is     SI_Unit;
  subtype Radian           is     SI_Unit;
  subtype Without_Unit     is     SI_Unit;
  -- Other SI units

  type Degree is new Big_Bang.Primeval_Float;

  function Degree_To_Radian (D: Degree) return Radian;
  function Radian_To_Degree (R: Radian) return Degree;

  -- Types without mathematics:

  type Kilometer is new Big_Bang.Primeval_Float_Without_Mathematics;

  function Kilometer_To_Meter (km: Kilometer) return Meter;
  function Meter_To_Kilometer ( m: Meter    ) return Kilometer;

  type    Nautical_Unit is new Big_Bang.Primeval_Float_Without_Mathematics;
  subtype Nautical_Mile is     Nautical_Unit;
  subtype Hour          is     Nautical_Unit;
  subtype Knots         is     Nautical_Unit;

  function Nautical_Mile_To_Meter (NMi: Nautical_Mile) return Meter ;
  function Meter_To_Nautical_Mile (m : Meter ) return Nautical_Mile;

  function Hour_To_Second (h: Hour  ) return Second;
  function Second_To_Hour (s: Second) return Hour;

  function Knots_To_Meter_Per_Second (kts: Knots           ) return Meter_Per_Second;
  function Meter_Per_Second_To_Knots (mps: Meter_Per_Second) return Knots;

  -- Other non SI units and conversion functions from and to SI units

  -- Hide faulty functions:

  function SinD (X: Radian) return SI_Unit renames Sin;   -- 1
  function Sin  (X: Degree) return Degree  renames SinD;  -- 2
  -- Remaining trigonometric functions and their inverses

  -- Declaration of new functions:

  function Sin  (X: Degree) return SI_Unit;
  function SinD (X: Degree) return SI_Unit renames Sin;
  -- Remaining trigonometric functions and their inverses

end Universe;

Remarks on the code:

1 This renaming declaration hides the faulty implicitly declared function which interpretes the argument in degrees, i.e. the hidden SinD function returns 1 for x = 90 rad, whereas the new (correct) function returns this value for x = PI/2 rad.

2 This hides the faulty implicitly declared function which interpretes the argument in radians.

The package has to be thoroughly tested, because on the one hand misspellings and omitted qualifications are apt to lead to the wrong results, and on the other hand compilers might produce faulty code because of the interaction between implicit and explicit declarations in connection with heavy overloading. In the given case, usage of pragma Inline was harmful and the order of hiding of wrong functions and declaration of new overloadings was essential although there must be no order dependence of the semantics in this respect.

Back to text.