comp.lang.ada
 help / color / mirror / Atom feed
From: "John G. Volan" <johnvolan@sprintmail.com>
Subject: Re: Naming of Tagged Types and Associated Packages
Date: 1998/09/05
Date: 1998-09-05T00:00:00+00:00	[thread overview]
Message-ID: <35F15C7D.A33C272E@sprintmail.com> (raw)
In-Reply-To: m367f9rhdj.fsf@mheaney.ni.net

[Cross-posted to comp.lang.eiffel, since I've added Eiffel content]

Matthew Heaney wrote:
>
> "John G. Volan" <johnvolan@sprintmail.com> writes:
>

[...snip...]

> 3) Name scalar types using the units in the name, ie
> 
>    type Heading_In_Degrees is ...; 

[...snip...]

> > As I've pointed out in the past, if it's important to say something in
> > a type name, there could easily be a case where it's important to say
> > it in the variable name too:
> >
> >      Speed_In_MPH : Speed_In_MPH_Type;
> >      Speed_In_Knots : Speed_In_Knots_Type;
> >      ...
> >      Speed_In_Knots := To_Knots(Speed_In_MPH);
> 
> See my point above.
> 
> The times when I care about the specific units of speed are only a
> subset of all the times I manipulate a speed.  When I really do care
> about the units, I just navigate to the declaration, the read units from
> the type name.
> 
> You don't need to tell me the units every single time, because I don't
> care about units every single time.  And when I don't care, I have to
> mentally parse it out.

I'm not saying that such details need to be stated at _all_ times. I can
accept dropping prefixes and suffixes if the context allows, e.g.:

    type Ship_Type is
      record
        Speed : Speed_In_Knots_Type;
        ...
      end record;

    Ship : Ship_Type;

    ... Ship.Speed ... -- we can look up the declaration to remind us of
                       -- the units

I'm merely saying that these suffixes and prefixes may be needed at
_some_ time, when the context forces us to disambiguate things, as in my
example you quoted above.  

If you had to do the above conversion using your naming scheme, how
would you declare the two different "speed" objects?  You rely on being
able to drop a
unit suffix to generate a variable name distinct from the type name. But
in the above situation, these suffixes are needed again to disambiguate
the two variables, which otherwise would have wound up with the same
name according to your scheme.

If your answer is, "Well, I'll just come up with some abbreviations for
the speed in knots variable vs. the speed in mph variable," then I'd
say, okay, you're free to do so, but then you'd have to admit that you
were doing something  ad-hoc.

Remember, the reason we're forced into all these contortions is because
of Ada's case insensitivity, combined with its strict insistence that
type names and variable names share a single namespace (within a given
scope).  In a language that relaxes either of these properties, we don't
have a problem. For instance, in Eiffel we might have:

    expanded class SPEED_IN_MPH   inherit DOUBLE feature ... end
    expanded class SPEED_IN_KPH   inherit DOUBLE feature ... end
    expanded class SPEED_IN_KNOTS inherit DOUBLE feature ... end

    class SHIP feature
        speed: SPEED_IN_KNOTS
        ...
    end -- class SHIP

And the above conversion situation would be something like:

    speed_in_mph: SPEED_IN_MPH;
    speed_in_knots: SPEED_IN_KNOTS;
    ...
    speed_in_knots := to_knots (speed_in_mph)


> > Or perhaps we should consider the word "Speed" to be unnecessary noise:
> >
> >      MPH : MPH_Type;
> >      Knots : Knots_Type;
> >      ...
> >      Knots := To_Knots(MPH);
> >      ...
> >      Set_Speed (Car, MPH => 10.0);
> >
> > Perhaps "Speed" could be the name of the package that houses the
> > MPH_Type and Knots_Type, and the To_Knots function, etc...
> 
> I don't like this idea.  The characteristics of the supporting type,
> such as whether it's fixed or float, the digits of precision, range,
> etc, are determined by the larger abstraction.  So I usually place the
> attribute types there, with the abstraction they describe.

If I'm reading this right, what you're saying is that if an analysis of
the problem domain indicates that a car has a speed in miles per hour,
you'd put a Car_Speed_In_MPH type in the Cars package along with a
<Something>_Car type?

Suppose further analysis of the problem domain indicated that weather
conditions constituted an important abstraction (let's say the system
does fine engine and transmission control to improve traction and fuel
economy in adverse weather).  Then you might have a Wind_Speed_In_MPH
type in a Weather package.

Would these two speed types have no commonality?  Would you be forced to
do a lot of type-conversions to work with them both?  Why couldn't you
just have a single Speed_In_MPH_Type in a common package (regarding
Speeds) that could be shared between the Cars package and the Weather package?

I've often noted that Ada projects tend to proliferate a lot of
unnecessary, redundant representations for the same classes of physical
quantities.  Little attempt is made to standardize on a normalized set
of unit types and accuracies, so you wind up with a lot of complex,
redundant, and hard to maintain conversion code scattered all over the
system.  

Such projects might have benefited greatly if physical quantity types
had been treated as first-class abstractions in their own right, e.g.:

    package Speeds is

      type Speed_Type is private;

      function From_MPH   (MPH   : in Long_Float) return Speed_Type;
      function From_KPH   (KPH   : in Long_Float) return Speed_Type;
      function From_Knots (Knots : in Long_Float) return Speed_Type;
      ...
      function To_MPH   (Speed : in Speed_Type) return Long_Float;
      function To_KPH   (Speed : in Speed_Type) return Long_Float;
      function To_Knots (Speed : in Speed_Type) return Long_Float;
      ...
    private
      type Speed_Type is
        record
          MPH : Long_Float;
            -- arbitrary choice, might be changed 
            -- without affecting the abstraction
        end record;
    end Speeds;

    with Speed_Constants; use Speed_Constants;
    package body Speeds is

      function From_MPH (MPH : in Long_Float) return Speed_Type is
      begin
        return (MPH => MPH);
      end From_MPH;

      function From_KPH (KPH : in Long_Float) return Speed_Type is
      begin
        return (MPH => KPH * KPH_To_MPH);
      end From_KPH;

      function From_Knots (Knots : in Long_Float) return Speed_Type is
      begin
        return (MPH => Knots * Knots_To_MPH);
      end From_Knots;
      ...
      function To_MPH (Speed : in Speed_Type) return Long_Float is
      begin
        return Speed.MPH;
      end To_MPH;

      function To_KPH (Speed : in Speed_Type) return Long_Float is
      begin
        return Speed.MPH * MPH_To_KPH;
      end To_KPH;

      function To_Knots (Speed : in Speed_Type) return Long_Float is
      begin
        return Speed.MPH * MPH_To_Knots;
      end To_Knots;

      ...
    end Speed;
 

Here's a similar rendition in Eiffel:

    expanded class
        SPEED
    inherit
        SPEED_CONSTANTS;
            -- assume provides Mph_to_kph, Kph_to_mph, etc...
        DOUBLE_APPROXIMATION
            -- assume provides comparison functions that account
            -- for numeric inprecision in DOUBLE computations, e.g.:
            -- sufficiently_equal, sufficiently_greater, etc.
            -- Are such functions already available somewhere?
    feature
        mph: DOUBLE
            -- this happens to be the only attribute,
            -- but that is an arbitrary choice. The rest
            -- are conversion functions:

        kph: DOUBLE is
            do
                Result := mph * Mph_to_kph
            end

        knots: DOUBLE is
            do
                Result := mph * Mph_to_knots
            end
        ...

        set_mph (new_mph: DOUBLE) is
            do
                mph := new_mph
            ensure
                sufficiently_equal (mph, new_mph)
            end

        set_kph (new_kph: DOUBLE) is
            do
                mph := new_kph * Kph_to_mph
            ensure
                sufficiently_equal (kph, new_kph)
            end

        set_knots (new_knots: DOUBLE) is
            do
                mph := new_knots * Knots_to_mph
            ensure
                sufficiently_equal (knots, new_knots)
            end

         accelerate (delta_speed: SPEED) is
            do
                mph := mph + delta_speed.mph
            ensure
                sufficiently_equal (mph, mph + delta_speed.mph)
            end
         ...
     invariant
         kph_definition: 
             sufficiently_equal (mph * Mph_to_kph, kph);
         knots_definition:
             sufficiently_equal (mph * Mph_to_knots, knots);
         ...
     end -- class SPEED


An intriguing alternative possibility would be to make SPEED a deferred
class instead (an abstract type in Ada95 parlance):


    deferred class
        SPEED
    inherit
        SPEED_CONSTANTS;
            -- assume provides Mph_to_kph, Kph_to_mph, etc...
        DOUBLE_APPROXIMATION
            -- assume provides comparison functions that account
            -- for numeric inprecision in DOUBLE computations, e.g.:
            -- sufficiently_equal, sufficiently_greater, etc.
            -- Are such functions already available somewhere?
    feature
        mph:   DOUBLE is deferred end
        kph:   DOUBLE is deferred end
        knots: DOUBLE is deferred end
        ...

        set_mph (new_mph: DOUBLE) is
            deferred
            ensure
                sufficiently_equal (mph, new_mph)
            end

        set_kph (new_kph: DOUBLE) is
            deferred
            ensure
                sufficiently_equal (kph, new_kph)
            end

        set_knots (new_knots: DOUBLE) is
            deferred
            ensure
                sufficiently_equal (knots, new_knots)
            end

         accelerate (delta_speed: SPEED) is
            require
                delta_speed_exists: delta_speed /= Void
            deferred
            ensure
                sufficiently_equal (mph, mph + delta_speed.mph)
            end
         ...
     invariant
         kph_definition: 
             sufficiently_equal (mph * Mph_to_kph, kph);
         knots_definition:
             sufficiently_equal (mph * Mph_to_knots, knots);
         ...
     end -- class SPEED


Then, you could have different heirs of this class optimized for
specific units of measure:

     expanded class
         SPEED_IN_MPH
     inherit
         SPEED
     feature
         mph: DOUBLE

         kph: DOUBLE is
             do
                 Result := mph * Mph_to_kph
             end

         knots: DOUBLE is
             do
                 Result := mph * Mph_to_knots
             end
         ...
         accelerate (delta_speed: SPEED) is
             do
                 mph := mph + delta_speed.mph
             end
         ...
     end -- class SPEED_IN_MPH


     expanded class
         SPEED_IN_KPH
     inherit
         SPEED
     feature
         mph: DOUBLE is
             do
                 Result := kph * Kph_to_mph
             end

         kph: DOUBLE

         knots: DOUBLE is
             do
                 Result := kph * Kph_to_knots
             end
         ...
         accelerate (delta_speed: SPEED) is
             do
                 kph := kph + delta_speed.kph
             end
         ...
      end -- end class SPEED_IN_KPH


      ... similarly for SPEED_IN_KNOTS, etc.


Then a class like CAR could have a SPEED attribute that could avail
itself of polymorphism:


      class CAR creation
          make
      feature -- Status report
          speed: SPEED

      feature -- Status setting

          set_speed (new_speed: SPEED) is
              require
                  speed_exists: new_speed /= Void
              do
                  speed := new_speed;
              end
          ...
      feature {NONE} -- Initialization
          make is
              do
                  ...
                  !SPEED_IN_MPH! speed
                      -- default to optimize on miles per hour,
                      -- but can be changed later (via set_speed)
                      -- to optimize on other units                      
                  ...
              end
          ...
      invariant
          speed_exists: speed /= Void
          ...
      end -- class CAR


-- 
indexing
   description: "Signatures for John G. Volan"
   self_plug: "Ex Ada guru", "Java 1.1 Certified", "Eiffelist wannabe"
   two_cents: "Java would be even cooler with Eiffel's assertions/DBC, %
              %generics, true MI, feature adaptation, uniform access, %
              %selective export, expanded types, etc., etc..."
class JOHN_VOLAN_SIGNATURE inherit SIGNATURE invariant
   disclaimer: not (opinion implies employer.opinion)
end -- class JOHN_VOLAN_SIGNATURE




  parent reply	other threads:[~1998-09-05  0:00 UTC|newest]

Thread overview: 138+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
1998-07-16  0:00 Naming of Tagged Types and Associated Packages taashlo
1998-07-25  0:00 ` Matthew Heaney
1998-07-25  0:00   ` Jean-Pierre Rosen
1998-07-25  0:00     ` Brian Rogoff
1998-07-26  0:00       ` Matthew Heaney
1998-07-26  0:00     ` Matthew Heaney
1998-07-26  0:00       ` nabbasi
1998-07-26  0:00         ` Matthew Heaney
1998-07-26  0:00         ` Robert Dewar
1998-07-27  0:00       ` Jean-Pierre Rosen
1998-07-28  0:00         ` Matthew Heaney
1998-07-28  0:00           ` Jean-Pierre Rosen
1998-07-28  0:00             ` dennison
1998-07-29  0:00               ` Jean-Pierre Rosen
1998-07-29  0:00                 ` dennison
1998-07-29  0:00                   ` Jean-Pierre Rosen
1998-07-30  0:00                     ` dennison
1998-07-30  0:00                       ` Jean-Pierre Rosen
1998-07-29  0:00         ` Robert I. Eachus
1998-07-30  0:00           ` Matthew Heaney
1998-07-30  0:00           ` Jean-Pierre Rosen
1998-07-30  0:00             ` Robert I. Eachus
1998-07-31  0:00               ` Jean-Pierre Rosen
1998-07-31  0:00                 ` Robert I. Eachus
1998-08-01  0:00                   ` Jean-Pierre Rosen
1998-08-04  0:00                     ` Matthew Heaney
1998-08-04  0:00                       ` Jean-Pierre Rosen
1998-08-10  0:00                         ` Robert I. Eachus
1998-07-27  0:00       ` dennison
1998-07-27  0:00         ` Stephen Leake
1998-07-27  0:00           ` dennison
1998-07-27  0:00             ` Brian Rogoff
1998-07-28  0:00               ` dennison
1998-07-28  0:00                 ` Brian Rogoff
1998-07-28  0:00                   ` dennison
1998-07-29  0:00                     ` Matthew Heaney
1998-07-29  0:00                       ` Chris Brand
1998-07-30  0:00                         ` Matthew Heaney
1998-07-30  0:00                           ` dennison
1998-07-30  0:00                             ` Matthew Heaney
1998-07-30  0:00                               ` dennison
1998-08-01  0:00                           ` Simon Wright
1998-08-02  0:00                             ` Matthew Heaney
1998-08-03  0:00                               ` dennison
1998-08-03  0:00                                 ` Matthew Heaney
1998-08-04  0:00                                   ` dennison
1998-08-04  0:00                               ` Jean-Pierre Rosen
1998-08-04  0:00                                 ` Brian Rogoff
1998-08-05  0:00                               ` Don Harrison
1998-08-05  0:00                                 ` Matthew Heaney
1998-08-07  0:00                                   ` Don Harrison
1998-08-13  0:00                                     ` Robert A Duff
1998-08-14  0:00                                       ` Don Harrison
1998-08-14  0:00                                       ` adam
1998-08-05  0:00                                 ` Brian Rogoff
1998-08-07  0:00                                   ` Don Harrison
1998-08-07  0:00                                   ` doylep
1998-08-07  0:00                                     ` Brian Rogoff
1998-08-08  0:00                                       ` Matthew Heaney
1998-08-10  0:00                                       ` doylep
1998-08-10  0:00                                         ` Brian Rogoff
1998-08-10  0:00                                           ` John Volan
1998-08-10  0:00                                           ` John Volan
1998-08-11  0:00                                           ` doylep
1998-08-11  0:00                                             ` Brian Rogoff
1998-08-13  0:00                                               ` Robert A Duff
1998-08-13  0:00                                                 ` Brian Rogoff
1998-09-01  0:00                                                 ` Matthew Heaney
1998-09-01  0:00                                                   ` Dale Stanbrough
1998-09-01  0:00                                                     ` Matthew Heaney
1998-09-01  0:00                                                       ` Bob Collins
1998-09-02  0:00                                                         ` Matthew Heaney
1998-09-04  0:00                                                       ` John G. Volan
1998-08-11  0:00                                         ` Don Harrison
1998-08-11  0:00                                           ` Pat Rogers
1998-08-11  0:00                                             ` Don Harrison
1998-09-01  0:00                                               ` Matthew Heaney
1998-08-13  0:00                                         ` Robert A Duff
1998-08-13  0:00                                           ` Brian Rogoff
1998-08-15  0:00                                             ` Don Harrison
1998-08-15  0:00                                               ` Jean-Pierre Rosen
1998-08-18  0:00                                                 ` Don Harrison
1998-08-14  0:00                                           ` Don Harrison
1998-08-17  0:00                                             ` doylep
1998-08-19  0:00                                               ` Don Harrison
1998-08-12  0:00                                       ` Don Harrison
1998-08-08  0:00                                     ` Matthew Heaney
1998-08-08  0:00                                       ` John G. Volan
1998-08-09  0:00                                         ` Matthew Heaney
1998-08-10  0:00                                           ` John G. Volan
1998-08-11  0:00                                             ` John Volan
1998-08-11  0:00                                             ` Don Harrison
1998-08-11  0:00                                               ` geoff
1998-08-31  0:00                                             ` Matthew Heaney
1998-08-31  0:00                                               ` Tucker Taft
1998-09-06  0:00                                                 ` John G. Volan
1998-09-06  0:00                                                   ` Matthew Heaney
1998-09-04  0:00                                               ` John G. Volan
1998-09-05  0:00                                                 ` Matthew Heaney
1998-09-05  0:00                                                   ` John G. Volan
1998-09-04  0:00                                               ` John G. Volan
1998-09-05  0:00                                                 ` John G. Volan
1998-09-06  0:00                                                   ` Matthew Heaney
1998-09-06  0:00                                                 ` Matthew Heaney
1998-09-04  0:00                                               ` John G. Volan
1998-09-06  0:00                                                 ` Matthew Heaney
1998-09-06  0:00                                                   ` John G. Volan
1998-09-06  0:00                                                   ` John G. Volan
1998-09-06  0:00                                                     ` Brian Rogoff
1998-09-06  0:00                                                       ` John G. Volan
1998-09-07  0:00                                                         ` Brian Rogoff
1998-09-07  0:00                                                           ` John G. Volan
1998-09-16  0:00                                                             ` Matthew Heaney
1998-09-05  0:00                                               ` John G. Volan [this message]
1998-09-05  0:00                                               ` John G. Volan
1998-08-11  0:00                                       ` doylep
1998-08-05  0:00                           ` Static Polymorphism (Was Re: Naming of Tagged Types...) Brian Rogoff
1998-08-06  0:00                             ` Matthew Heaney
1998-08-06  0:00                               ` Brian Rogoff
1998-07-28  0:00                   ` Naming of Tagged Types and Associated Packages Brian Rogoff
1998-07-29  0:00                     ` Matthew Heaney
1998-07-29  0:00                       ` Brian Rogoff
1998-07-28  0:00             ` Norman H. Cohen
1998-07-28  0:00               ` Stephen Leake
1998-07-28  0:00               ` Matthew Heaney
1998-07-28  0:00         ` Matthew Heaney
1998-07-28  0:00           ` Jean-Pierre Rosen
1998-07-28  0:00             ` Matthew Heaney
1998-07-28  0:00               ` dennison
1998-07-29  0:00                 ` Matthew Heaney
1998-07-30  0:00                 ` Robert Dewar
1998-07-30  0:00                   ` Matthew Heaney
1998-08-06  0:00         ` Robert A Duff
1998-08-06  0:00           ` Matthew Heaney
1998-08-06  0:00             ` Tucker Taft
1998-08-31  0:00               ` Matthew Heaney
  -- strict thread matches above, loose matches on Subject: below --
1998-07-26  0:00 tmoran
1998-07-27  0:00 ` dennison
replies disabled

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