comp.lang.ada
 help / color / mirror / Atom feed
* assignments using different types
@ 1997-01-28  0:00 David Dessert
  1997-01-28  0:00 ` Christopher Green
                   ` (4 more replies)
  0 siblings, 5 replies; 10+ messages in thread
From: David Dessert @ 1997-01-28  0:00 UTC (permalink / raw)



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.

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;

   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.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: assignments using different types
  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
                   ` (3 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Christopher Green @ 1997-01-28  0:00 UTC (permalink / raw)



In article <32EE4431.6D24@ti.com>, David Dessert  <d-dessert@ti.com> wrote:
>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.
>
>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;
>
>   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.

If your compiler does something useful with "pragma Inline", the following
is no less efficient and quite a bit more expressive.  I've extended the
example to show the expressiveness of using the type system and operators
together...

    type Distance_Type is new float;
    type Time_Type is new float;
    type Velocity_Type is new float;
    type Acceleration_Type is new float;

    -- note that the inlined functions' names are chosen to be unique:
    -- this avoids problems with attempting to inline functions that
    -- have overloaded names.

    function V_Is_Dx_Dt (Left : in Distance_Type; Right : in Time_Type)
      return Velocity_Type;
    pragma Inline (V_Is_Dx_Dt);

    function A_Is_Dv_Dt (Left : in Velocity_Type; Right : in Time_Type)
      return Acceleration_Type;
    pragma Inline (A_Is_Dv_Dt);

    -- these are so we can invoke our definitions as operators.

    function "/" (Left : in Distance_Type; Right : in Time_Type)
      return Velocity_Type renames V_Is_Dx_Dt;

    function "/" (Left : in Velocity_Type; Right : in Time_Type)
      return Acceleration_Type renames A_Is_Dv_Dt;

    -- the type conversions are buried in the function bodies.

    function V_Is_Dx_Dt (Left : in Distance_Type; Right : in Time_Type)
      return Velocity_Type is
    begin
      return Velocity_Type (float (Left) / float (Right));
    end V_Is_Dx_Dt;

    function A_Is_Dv_Dt (Left : in Velocity_Type; Right : in Time_Type)
      return Acceleration_Type is
    begin
      return Acceleration_Type (float (Left) / float (Right));
    end A_Is_Dv_Dt;

    -- and later on, simply write...

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

    Velocity     := Distance / Time;
    Acceleration := Velocity / Time;

Chris Green                                  Email cgreen@atc.com
Advanced Technology Center                   Phone (714) 583-9119
22982 Mill Creek Drive                                   ext. 220
Laguna Hills, CA 92653                       Fax   (714) 583-9213




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: assignments using different types
  1997-01-28  0:00 assignments using different types David Dessert
                   ` (3 preceding siblings ...)
  1997-01-29  0:00 ` assignments using different types Robert Dewar
@ 1997-01-29  0:00 ` Paul Van Bellinghen
  1997-02-10  0:00   ` Robert Dewar
  4 siblings, 1 reply; 10+ messages in thread
From: Paul Van Bellinghen @ 1997-01-29  0:00 UTC (permalink / raw)



why are you re-casting variables that are already in the proper cast.
The only time you need to re-cast a variable into float is when the
variable is an integer.

On Tue, 28 Jan 1997 12:23:45 -0600, David Dessert <d-dessert@ti.com>
wrote:

>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.
>
>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;
>
>   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.





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: assignments using different types
  1997-01-28  0:00 assignments using different types David Dessert
                   ` (2 preceding siblings ...)
  1997-01-29  0:00 ` Robert Dewar
@ 1997-01-29  0:00 ` Robert Dewar
  1997-01-29  0:00 ` Paul Van Bellinghen
  4 siblings, 0 replies; 10+ messages in thread
From: Robert Dewar @ 1997-01-29  0:00 UTC (permalink / raw)



iDavid asks

"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;

   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."

Robert replies

Most certainly: define an approrpiate "/" operator, mark it to be inlined
with pragma Inline, and then just write

  Velocity := Distance / Time;





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: assignments using different types
  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
@ 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 Robert Dewar
  1997-01-29  0:00 ` Paul Van Bellinghen
  4 siblings, 1 reply; 10+ messages in thread
From: Robert Dewar @ 1997-01-29  0:00 UTC (permalink / raw)



By the way, in my response to this just now, I suggested using pragma
Inline, which brings to mind the big discussion we had about inlining.

Well just as a postscript to that discussion. GNAT 3.09 implements
the -gnatN switch which asks for all possible inter-unit inlining to
be carried out. This *just* made it into the release, but did not
make it into the documentation yet!





^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: assignments using different types
  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
  1997-01-29  0:00 ` Robert Dewar
                   ` (2 subsequent siblings)
  4 siblings, 0 replies; 10+ messages in thread
From: Robert I. Eachus @ 1997-01-29  0:00 UTC (permalink / raw)




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...




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: assignments using different types
@ 1997-01-29  0:00 tmoran
  0 siblings, 0 replies; 10+ messages in thread
From: tmoran @ 1997-01-29  0:00 UTC (permalink / raw)



>   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

  How about creating

function "/"(Distance : in Distance_Type;
             Time     : in Time_Type)
return Velocity_Type is
begin
  return Velocity_Type(float(Distance) / float(Time));
end "/";

  and then you will be able to write

Velocity := Distance / Time;

(Actually, your current statement is quite readable - though tedious
to write.)




^ permalink raw reply	[flat|nested] 10+ messages in thread

* inter-unit inlining (was: Re: assignments using different types)
  1997-01-29  0:00 ` Robert Dewar
@ 1997-01-30  0:00   ` Fergus Henderson
  0 siblings, 0 replies; 10+ messages in thread
From: Fergus Henderson @ 1997-01-30  0:00 UTC (permalink / raw)



dewar@merv.cs.nyu.edu (Robert Dewar) writes:

>By the way, in my response to this just now, I suggested using pragma
>Inline, which brings to mind the big discussion we had about inlining.
>
>Well just as a postscript to that discussion. GNAT 3.09 implements
>the -gnatN switch which asks for all possible inter-unit inlining to
>be carried out.

Cool!

--
Fergus Henderson <fjh@cs.mu.oz.au>   |  "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh>   |  of excellence is a lethal habit"
PGP: finger fjh@128.250.37.3         |     -- the last words of T. S. Garp.




^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: assignments using different types
@ 1997-01-30  0:00 Thomas
  0 siblings, 0 replies; 10+ messages in thread
From: Thomas @ 1997-01-30  0:00 UTC (permalink / raw)



--
On  29 Jan 1997 17:34:54 GMT,  tmoran@bix.com wrote ...
 > >   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
 > 
 >   How about creating
 > 
 > function "/"(Distance : in Distance_Type;
 >              Time     : in Time_Type)
 > return Velocity_Type is
 > begin
 >   return Velocity_Type(float(Distance) / float(Time));
 > end "/";
 > 
 >   and then you will be able to write
 > 
 > Velocity := Distance / Time;
 > 
 > (Actually, your current statement is quite readable - though tedious
 > to write.)
--






^ permalink raw reply	[flat|nested] 10+ messages in thread

* Re: assignments using different types
  1997-01-29  0:00 ` Paul Van Bellinghen
@ 1997-02-10  0:00   ` Robert Dewar
  0 siblings, 0 replies; 10+ messages in thread
From: Robert Dewar @ 1997-02-10  0:00 UTC (permalink / raw)



Paul said

<<why are you re-casting variables that are already in the proper cast.
The only time you need to re-cast a variable into float is when the
variable is an integer.>>

This is quite wrong, it would be true in C, but is not just false for Ada.
It is the *essence* of a critical feature of Ada that it is false! In the
example you were commenting on, the float types were different types,
and the casts, called type conversions in ada, were definitely necessary.





^ permalink raw reply	[flat|nested] 10+ messages in thread

end of thread, other threads:[~1997-02-10  0:00 UTC | newest]

Thread overview: 10+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
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
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 Robert Dewar
1997-01-29  0:00 ` 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

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