comp.lang.ada
 help / color / mirror / Atom feed
From: eachus@spectre.mitre.org (Robert I. Eachus)
Subject: Re: assignments using different types
Date: 1997/01/29
Date: 1997-01-29T00:00:00+00:00	[thread overview]
Message-ID: <EACHUS.97Jan29141736@spectre.mitre.org> (raw)
In-Reply-To: 32EE4431.6D24@ti.com



In article <32EE4431.6D24@ti.com> David Dessert <d-dessert@ti.com> writes:

  > I have a question about readability and efficiency of assignments
  > when using strict types in Ada83.  I'm using the TI-Tartan C40
  > compiler, which has few Ada95 features.

  (In spite of the above comment, I'll answer for Ada 95, then relate
back to Ada 83.)

  > Example:
  >    type Distance_Type is new float range 0.0 .. 1000.0;
  >    type Time_Type is new float range 0.0 .. 10.0;
  >    type Velocity_Type is new float;

   In Ada 95, you should immediately declare:

   function "*"(L,R: Distance_Type) return Distance_Type is abstract;
   function "/"(L,R: Distance_Type) return Distance_Type is abstract;
   function "*"(L,R: Time_Type) return Time_Type is abstract;
   function "/"(L,R: Time_Type) return Time_Type is abstract;
   function "*"(L,R: Velocity_Type) return Velocity_Type is abstract;
   function "/"(L,R: Velocity_Type) return Velocity_Type is abstract;
   
   -- These declarations will have no effect at run-time, but will
   -- eliminate many type errors.  (These declarations are Ada 95 only.)

   -- Now you can introduce the correct multiplication and division
   -- operations:

   function "*"(L: Velocity_Type, R: Time_Type) return Distance_Type;
   function "*"(L: Time_Type, R: Velocity_Type) return Distance_Type;

   function "/"(L: Distance_Type, R: Time_Type) return Velocity_Type;
   function "/"(L: Distance_Type, R: Velocity_Type) return Time_Type;
   -- The bodies are easy, just remember to convert to float...

   pragma Inline("*","/");
   --might as well get rid of the overhead...

      Distance : Distance_Type := 100.0;
      Time     : Time_Type     := 10.0;
      Velocity : Velocity_Type;

   ...

      -- A difficult to read, but legal Ada assignment.
      Velocity := Velocity_Type(float(Distance) / float(Time));

 > Can anyone provide me with suggestions to improve the readability
 > of the above assignment?  Of course, I'd like efficiency to be
 > similar to that of using the same type for all the variables.

    -- Now you can write that:

       Velocity := Distance / Time;

    There can be a need for qualification if you use literals in an
expression, but that is a detail.

    In Ada 83, the abstract declarations are not possible.  You can
just leave them out which won't affect correct programs.  Or you can
use private types:

    type Distance_Type is private;
    type Time_Type is private;
    type Velocity_Type is private;

    Now you may need to declare the adding and relational operators,
but the real problem is that you lose the literals.  So you have to
declare:
 
    function To_Time(T: in Float) return Time_Type;
    ...

    Distance : Distance_Type := To_Distance(100.0);
    Time     : Time_Type     := To_Time(10.0);
    Velocity : Velocity_Type;

    However a lot of people prefer to declare the constants and
operators necessary to write:

    Distance : Distance_Type := 100.0 * Kilometers;
    Time     : Time_Type := 10.0 * Hours;
    
     But that is not my style.  (I'd prefer to name Distance_Type
Kilometers or Miles or whatever, and do the same for time and
velocity.)

     If you have lots of different units in a program, you might want
to look at something Paul Hilfinger came up with years ago.  He made
 a single measurement record type with integer discriminants.  So
velocity would be:

     subtype Velocity is Measurement(Mass => 0, Length => 1, Time => -1); 

     Now all the operations can check dimensionality.  What is really
neat is to then recompile with a body where all the dimensional checks
are gone.  With a good compiler the overhead will completely
disappear.  (You can change the type and subtype declarations if
the compiler is not quite so smart.)  But any good compiler will give
you a warning if the units don't match at compile time, so recompiling
is not leaving off the lifeboats since you know the checks will never
fail--at least until the maintenance staff gets their hands on it. ;-)
--

					Robert I. Eachus

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




  parent reply	other threads:[~1997-01-29  0:00 UTC|newest]

Thread overview: 10+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1997-01-28  0:00 assignments using different types David Dessert
1997-01-28  0:00 ` Christopher Green
1997-01-29  0:00 ` Robert I. Eachus [this message]
1997-01-29  0:00 ` Robert Dewar
1997-01-29  0:00 ` Robert Dewar
1997-01-30  0:00   ` inter-unit inlining (was: Re: assignments using different types) Fergus Henderson
1997-01-29  0:00 ` assignments using different types Paul Van Bellinghen
1997-02-10  0:00   ` Robert Dewar
  -- strict thread matches above, loose matches on Subject: below --
1997-01-29  0:00 tmoran
1997-01-30  0:00 Thomas
replies disabled

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