comp.lang.ada
 help / color / mirror / Atom feed
From: eachus@spectre.mitre.org (Robert I. Eachus)
Subject: Re: Tagged Types and Generics
Date: 1997/04/28
Date: 1997-04-28T00:00:00+00:00	[thread overview]
Message-ID: <EACHUS.97Apr28152546@spectre.mitre.org> (raw)
In-Reply-To: 3.0.32.19970421225247.007129f4@mail.4dcomm.com


In article <3.0.32.19970421225247.007129f4@mail.4dcomm.com> "Robert C. Leif, Ph.D." <rleif@RLEIF.COM> writes:

  > After the paper was submitted, I attempted to do my suggestion and
  > model money as a tagged type with the child libraries being the
  > different currencies.  If one makes the exchange rate a decimal
  > type, then currency conversion requires a decimal division of the
  > same field from two of the child library units.

   Let's deal with two separate problems separately.  You want to have
an abstract general currency type, then derive to create different
currencies.  So far so good.  But your abstract type will have
non-currency operations.  If you do it right though objects won't
contain fields other than the fixed point field.  I see creating a
generic that takes a formal decimal type, a string or two, etc.  and
creates a new type derived from Currency with all these nice
properties.
 
   Next problem, you want to convert between two decimal types.  Once
you understand that this is a non-transitive relationship, you create
a generic conversion function in the Currencies package that needs to
do one of three things: 1) some very clever conversion code 2) use
floating point or 3) overflow under unexpected circumstances.  Lets
choose choice 1...


   package Currencies is

      type Currency is abstract tagged private;

      function Symbol(Value: in Currency) return String is abstract;

      function Name(Value: in Currency) return String is abstract;

      function "+"(L,R: Currency) return Currency is abstract;
      ...
      function To_String(Value: in Currency) return String;

   private

      type Currency is ...;

      function Integer_Part(Value: in Currency) return String is abstract;
      function Fractional_Part(Value: in Currency) return String is abstract;

   end Currencies;
 
   generic
      type Decimal is delta <> digits <>;
      Symbol: in String;
      Name: in String;
   package Currencies.Create is

      type Local is new Currencies.Currency with private;

      function "+" (L,R: Local) return Local;...

   private

      type Local is new Currencies.Currency with record
         Value: Decimal := 0.0;
      end record;

   end Currencies.Create;

   generic
      type From is new Currency;
      type To is new Currency;
      Multiplier: in String; -- i.e. "123.456789"
   function Conversion(Amount: in From) return To;

   function Conversion(Amount: in From) return To is
   begin
      return Integer'Value(Integer_Part(Amount)) * From'Value(Multiplier)
         + From'Value(Fractional_Part(Amount)) * From'Value(Multiplier);
   exception 
      when others => TBD;
   end Conversion;

   You might want to use a rational arithmetic package instead, or
some such.  But the real problem is that currency conversions will
change in how they are specified and computed a lot faster than your
software.  You really do need to accept arbitrarily long strings of
zeros--which I didn't do here--when a currency devalues rapidly.

--

					Robert I. Eachus

with Standard_Disclaimer;
use  Standard_Disclaimer;
function Message (Text: in Clever_Ideas) return Better_Ideas is...




  parent reply	other threads:[~1997-04-28  0:00 UTC|newest]

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-04-21  0:00 Tagged Types and Generics Robert C. Leif, Ph.D.
1997-04-24  0:00 ` Jeff Carter
1997-04-25  0:00 ` Robert Dewar
1997-04-26  0:00   ` Matthew Heaney
1997-04-26  0:00   ` Tom Moran
1997-04-27  0:00   ` Nick Roberts
1997-04-28  0:00 ` Robert I. Eachus [this message]
1997-04-28  0:00   ` Tom Moran
  -- strict thread matches above, loose matches on Subject: below --
1997-04-26  0:00 Robert C. Leif, Ph.D.
1997-04-27  0:00 ` Robert Dewar
1997-05-02  0:00   ` Nick Roberts
replies disabled

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox