comp.lang.ada
 help / color / mirror / Atom feed
From: "Robert C. Leif, Ph.D." <rleif@RLEIF.COM>
Subject: Tagged Types and Generics
Date: 1997/04/21
Date: 1997-04-21T00:00:00+00:00	[thread overview]
Message-ID: <3.0.32.19970421225247.007129f4@mail.4dcomm.com> (raw)


From: Bob Leif, Ph.D.

To: Comp.Lang.Ada
Date: 21 April, 1997
Subject: Tagged Types and Generics.

Background: Recently, Tom Moran, Randy Brukard and I wrote a paper. "Ada
95, The Language Speaks for Itself".  This paper will appear in the May
Object Magazine.  In this paper we modeled money as a decimal type and did
inheritance directly via a generic.  I had suggested modeling money as a
tagged type.  My co-authors very wisely vetoed that approach.  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.  I created a function with class based types and tried to
instantiate the generic procedure Divide in the Annex F Package
Ada.Decimal.  My lack of success is described in the listing of the body
below.  The program has been reduced and modified to demonstrate the
problem.  I know that I could probably get away with using a floating point
type.  However, if we are to sell Ada to the MIS world based in part on its
capacity to do decimal arithmetic, then we should employ decimal arithmetic
in our programs.

I do not know how to pass the type an element in a tagged record to a
generic.  I tried recreating the type by including the values of the Scale
and Digits attributes in the tagged record.  I would appreciate suggestions
and hope for a solution that I could show at the ACM SigAda booth at Object
Expo in New York City from 2-5 June, 1997.

Both the specification and body were compiled under GNAT for Windows.
gcc -c -gnatlv dec_divide.adb > dec_divide.txt

Specification source.

  generic

      type Num_Or_Denom is delta <> digits <>;
      type Ratio is delta <> digits <>;

      package Dec_Divide is

      type Num_Or_Denoms is abstract tagged private;
     --This the start of the class

    Function Ratio_Test(Numerator : in Num_Or_Denoms'Class;
                        Denominator : in Num_Or_Denoms'Class)
                        return Ratio;
Private
      type Num_Or_Denoms is abstract tagged
            record
            The_Num_Or_Denom : Num_Or_Denom;
            Num_Or_Denom_Scale: Integer := Num_Or_Denom'Scale;
            Num_Or_Denom_digits: Integer := Num_Or_Denom'digits ;
                         end record;
   end Dec_Divide;

----------------------------------------------------------------------------
------------------------------
Listing of body.
GNAT 3.09 (970121) Copyright 1991-1996 Free Software Foundation, Inc.

Compiling: dec_divide.adb (source file time stamp: 1997-04-22 05:24:59)

     1. -- From Ada 95 Referance Manual pages 47-48 Section 3.5.10
     2. -- S'Scale
     3. -- S'Scale denotes the scale of the subtype S, defined as the
     4. -- value N such that S'Delta = 10.0**(-N). The scale indicates
     5. -- the position of the point relative to the rightmost
     6. -- significant digits of values of subtype S. The value
     7. -- of this attribute is of the type universal_integer.
     8.
     9. -- Note 38. S'Scale is not always the same as S'Aft for a
    10. -- decimal subtype; for example, if S'Delta = 1.0 then S'Aft
    11. -- is 1 while S'Scale is 0.
    12.
    13. --S'Digits
    14. --S'Digits denotes the digits of the decimal fixed point subtype S,
    15. --which corresponds to the number of decimal digits that are
    16. --representable in objects of the subtype. The value of this attribute
    17. --is of the type universal_integer.
    18.
    19. -- Note 39. The predefined operations of a fixed point type
    20. -- include the assignment operation, qualification,
    21. -- the membership tests, and explicit conversion to and
    22. -- from other numeric types. They also include the relational
    23. -- operators and the following predefined arithmetic operators:
    24. -- the binary and unary adding operators - and +,
    25. -- multiplying operators, and the unary operator abs.
    26.
    27.    with Ada.Decimal;
    28.
    29.    package body Dec_Divide is
    30.       Function Ratio_Test(Numerator : in Num_Or_Denoms'Class;
    31.                           Denominator : in Num_Or_Denoms'Class)
    32.       return Ratio is
    33.
    34.       --This may require access types for the decimals types, which
are
    35.       --dynamic rather than static. Maybe define box with a generic
in the
    36.       --specification and pass over. With a pointer, one gets a
general
    37.       --structure.
    38.
    39.          Type Gen_Numerator is delta
10.0**(-Numerator.Num_Or_Denom_Scale)
                                                 |
        >>> non-static expression used for delta value

    40.                 digits Numerator.Num_Or_Denom_digits;
                                        |
        >>> non-static expression used for digits value

    41.
    42.          Type Gen_Denominator is delta 10.0**(-
        Denominator.Num_Or_Denom_Scale)
                                                   |
        >>> non-static expression used for delta value

    43.                         digits Denominator.Num_Or_Denom_digits;
                                                  |
        >>> non-static expression used for digits value

    44.
    45.
    46.          Procedure Divide is new Ada.Decimal.Divide
    47.            (Dividend_type => Gen_Numerator,
    48.             Divisor_Type  => Gen_Denominator,
    49.             Quotient_Type => Ratio,
    50.             Remainder_Type => Ratio);
    51.
    52.          Use Divide;
                     |
        >>> "Divide" is not a usable package

    53.       The_Numerator: Gen_Numerator :=
                Gen_Numerator(Numerator.The_Num_Or_Denom);
    54.
    55.       The_Denominator:Gen_Denominator :=
                Gen_Denominator(Denominator.The_Num_Or_Denom);
    56.          The_Ratio: Ratio;
    57.          The_Remainder: Ratio;
    58.       begin --Ratio_Test
    59.
    60.          Divide
    61.             (Dividend => The_Numerator,
    62.             Divisor =>  The_Denominator,
    63.             Quotient => The_Ratio,
    64.             Remainder => The_Remainder);
    65.         Return The_Ratio;
    66.       end Ratio_Test;
    67.    end Dec_Divide;

 67 lines:

 Robert C. Leif, Ph.D., PMIAC
Vice President & Research Director
Ada_Med, a Division of Newport Instruments
5648 Toyon Road
San Diego, CA 92115-1022
Tel. & Fax (619) 582-0437
E-mail rleif@rleif.com




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

Thread overview: 11+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-04-21  0:00 Robert C. Leif, Ph.D. [this message]
1997-04-24  0:00 ` Tagged Types and Generics Jeff Carter
1997-04-25  0:00 ` Robert Dewar
1997-04-26  0:00   ` Tom Moran
1997-04-26  0:00   ` Matthew Heaney
1997-04-27  0:00   ` Nick Roberts
1997-04-28  0:00 ` Robert I. Eachus
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