comp.lang.ada
 help / color / mirror / Atom feed
From: Matthew Heaney <matthew_heaney@acm.org>
Subject: Re: Naming of Tagged Types and Associated Packages
Date: 1998/08/31
Date: 1998-08-31T00:00:00+00:00	[thread overview]
Message-ID: <m367f9rhdj.fsf@mheaney.ni.net> (raw)
In-Reply-To: 35CEBAAF.B9B82820@sprintmail.com

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

> Ada's mechanism is to force the identifiers to be literally different,
> which means either adding some kind of noise word to one or the other,
> or resorting to abbreviation for one or the other. Many react with
> distaste to either prospect, because they recognize both as catering
> to the programming language, and not to the problem domain concept we
> are trying to express. (Remember, the noun phrase in question is
> presumed to be both necessary and sufficient to express the concept.)
> Adding noise seems less obnoxious than abbreviation. So what's the
> least obnoxious noise you can add?

I do this sort of thing too:

   PDW : Pulse_Descriptor_Word;
   
   SOI : Signal_Of_Interest;

   Speed : Speed_In_Knots;

> I hope you recognize that "Root_" is as much a noise word as any
> other, because it caters to the mechanisms of the language rather than
> to the problem domain.  Most OO programmers would find it distasteful
> to mark the class at the top of an inheritance hierarchy this way,
> simply because it was at the top of an inheritance hierarchy.

I'm not sure I understand the argument that you have to "cater to the
language mechanisms."  Under what circumstances do you not have to cater
to the language mechanisms?  

Isn't this what this whole thread is about, how to program in Ada?  We
have to cater to the language mechanisms wrt naming of types (wrt to
anything, actually), so what's the best way to do that?
 
> But this is another tangent irrelevant to P.D.'s simple question, and
> it doesn't address the general case.  What if, for the particular
> problem domain at hand, "CAR" is _not_ intended as the top of an
> inheritance hierarchy?  In fact, what if we even wanted to _preclude_
> any inheritance?  (In Ada terms, the Car type would be non-tagged.  In
> Java, it would be a final class.  In Eiffel ... not sure of the
> syntax.)  In that case, attaching the "Root_" prefix would not only be
> noise, it would be misleading noise.

I would only use "Root_" as a prefix for the root type in a hierarchy of
tagged types.  Under no circumstances would I name a non-tagged type
"Root_".

> So the question remains: All things being equal, what's the least
> noxious noise you can add, that will work even in the most general
> case?

Again, we have different philosophies here.  You argue for a simple
solution ("_Type", I think) that can be applied mechanically, all the
time.  That's fine.  

However, I'm trying my best only use _Type as an indicator of static
polymorphism, and so am advocating a slighly more complicated
convention.  Note that this doesn't preclude mechanical application.
 
> With all these various cases, isn't your scheme really ad hoc?  

I wouldn't describe what I do as ad hoc.  If you've read the code in my
other posts, I'm sure you wouldn't describe it as ad hoc either.  You
might even be tempted to say it's sorta elegent.

> If you claim it is not ad hoc, can you articulate a finite number of
> rules that cover all situations (or at least a sufficient majority of
> them)?

Hmmm.  Let's see.

1) Name the (abstract) root of a hierarchy of tagged types Root_.

One exception (oops, an exception already, on the first bullet!) is if
there's already a good two-part name from the problem domain, use that
instead of Root_.  The classic example is Bank_Account, from which
Checking_Account and Savings_Account derive.

2) Name the type _Type to indicate static polymorphism, ie

   generic
      ...
   package Stacks_Unbounded is

      type Stack_Type is private;


   generic
      ...
   package Stacks_Bounded is
      
      type Stack_Type is private;


3) Name scalar types using the units in the name, ie

   type Heading_In_Degrees is ...;

4) If you often refer to an acronym, then use expanded name as the type, 

   SOI : Signal_Of_Interest;

   PDW : Pulse_Descriptor_Word;

5) Name arrays _Array, and name the array instance the plural:

   type Stack_Item_Array is 
      array (Positive range <>) of Stack_Item;

   Items : Stack_Item_Array;

6) Never ever name a scalar type as a plural

   type Tuner_Ids is range 1 .. 4;  -- you're a bad boy

I makes zero sense to see this

   Id : Tuner_Ids;

since we're only talking about a single object, not an array or set.  So
stick to the singular convention

   type Tuner_Id is range 1 .. 4;

   Id : Tuner_Id;


7) Use an adjective-noun phrase to name the type:

   Tuner_Id
   Character_Glyph
   Bounded_String
   File_Mode


> Why not just settle on a simpler and more systematic way to introduce
> the required noise, and have done with it? 

If you use _Type everywhere, it just becomes noise.  If I have to use an
extra word (I do), then I prefer that the word carry some useful
information.

> So why not just have a single rule: Consistently mark every type as
> such, and reserve the unmarked noun phrase for a possible variable
> name.  

See above.

> But the whole point is that every scheme introduces noise. We are only
> quibbling over which form of noise is the least distasteful.  

No.  The extra verbiage doesn't have to become noise - it can tell me
something useful (like the units).

> I could as easily say that the human reader is only interested that
> the thing is a "Car", and will just parse out the "Root_" part anyway;
> or that the thing is a "Steering_Wheel" from the "Cars" package, and
> will just parse out the "Car_" part anyway; so why not just parse out
> these noise words for him?

Because I wouldn't say that "Car_" is a noise word.
 
> But you see, you diverted the poor guy off onto a tangent.  What if he
> had responded, "Why, it's a color of anything that can _be_ colored,
> not just the color of a car.  In short, "Color" is an abstraction all
> its own, in a module of its own that is all about colors.

No.  I was talking specifically about the color attribute of a car
abstraction.  You have no guarantee that a car abstraction can have all
possible values for color.  Hence, Car_Color.

> I don't think the original designers of Text_IO necessarily completely
> thought through all the issues of naming conventions back then.  Isn't
> the "File_" part in "File_Mode" just a redundant re-iteration of the
> context, since we know that Text_IO is all about text files anyway?
> (I sometimes wish Text_IO had been named Text_Files instead, as this
> would have been a more "object-oriented" name; "Text Input/Output" is
> the _function_ this package supports, but "Text Files" are the
> _objects_ this package is _about_.)

Look at Text_IO as a machine (which it is).  It does more that just
export an ADT - it manages state too (Standard_Input, Standard_Output).

The name Text_Files would be misleading, because Text_IO is not an ADT
package - it's a singleton abstraction that happens to export an ADT.

> On the other hand, let's suppose "File_Mode" is a necessary and
> sufficient phrase to express the whole sense of the concept
> (presumably within a use-ophilic environment).  Maybe you can get away
> with dropping the "File_" adjective for a variable within the package,
> but can you always do that outside the package, in all its conceivable
> clients?  What if there's a context where you have both a "File_Mode"
> and some other kind of mode, say an "Operational_Mode" (e.g., Real vs.
> Simulated)?  Then it becomes important to use the complete names for
> those concepts, including the "File_" and "Operational_" prefixes, not
> just in their type names but also in the variable names.  If we now
> need "File_Mode" and "Operational_Mode" as variable names, what should
> the types have been called?

That does happen sometimes, especially subprogram parameters.  I would
probably do something like this:

  procedure Op
     (File  : in out File_Type;
      FMode : in     File_Mode;
      OMode : in     Operation_Mode);


> You know, I'm not averse to the idea, per se, of dropping prefixed
> adjectives when they can be understood from the context.  

I argue that you have to read the entire declaration to get all the
information.  Sometimes I see guys to this:

   procedure Op (... The_File_Mode : in File_Mode; ...);

but it all seems very redundent.  By reading the entire declaration,
including the type name, that I get all the information I need, but more
concisely, as in

   procedure Op (... Mode : in File_Mode; ...);

> 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.
 
> > When refering to a literal,
> > I like to use a qualified name, as in
> > 
> >    Set_Speed (Car, Speed => Speed_In_MPH'(10.0));
> 
> How about just:
> 
>      Set_Speed (Car, Speed_In_MPH => 10.0);

Then you've made the choice for the client.  I prefer that the client be
able to decide how much verbosity he wants to include at the point of
call.
 
> 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.

> Unless there's a situation where it becomes important again to
> distinguish it as a car's steering wheel, and we find we need to put
> that adjective back:
> 
>    Car_Steering_Wheel : Car_Steering_Wheel_Type := ...
>    Tow_Truck_Steering_Wheel : Tow_Truck_Steering_Wheel_Type := ...
>    ...
>    -- make the Car simulation physically 
>    -- follow the Tow_Truck simulation:
>    Set_Direction
       (Car_Steering_Wheel, Get_Direction (Tow_Truck_Steering_Wheel));

Well, I alluded to another technique, and that's to go ahead an use an
abbreviation, as in

   CWheel : Car_Steering_Wheel;
   TWheel : Truck_Steering_Wheel;

for those few times when you have two wheel objects in the same scope.


> > The Car_ part is there because we need to have a different name for the
> > type, because we want to call the object Steering_Wheel.
> 
> So basically you're saying the "Car_" part is just noise, right?

No.  "Car" is never noise.  "Car" is signal.

> But "Car_" doesn't tell me something I don't already know, either,
> right?  I mean, to understand the entire abstraction, we don't just
> look at a single _declaration_, we look at the whole _package_ that
> encapsulates it, right?  The package name "Cars" already says it all.

I'm a use-o-phile.  Therefore I'm not looking at the Cars package when
I'm reading the declaration of an object (because I didn't use an
expanded name).  So the Car_ is telling me something.

> > If we know that the object is going to be called Steering_Wheel, and
> > that we need a different (and longer) name for the type, then you might
> > as well add additional, substantive information about the abstraction
> > the type describes.
> 
> But what substantive information are you adding that hasn't already
> been supplied in other ways?
> 
>    with Cars;  -- assume this is written by a use-o-phobe
>    ...
>       My_Cars_Steering_Wheel : Cars.Car_Steering_Wheel;
>                                ^^^^^^^^
> 
> Isn't this redundant, and therefore noise?

I agree - there is redundancy.  We can resolve that in two ways:

1) use a use, and ditch the expanded name; or

2) don't use a use, and ditch the Car_ prefix.

I choose option 1).

> Some objects are indeed islands, if we choose to keep them uncoupled
> to other objects.  Making abstractions "go with" each other in a
> single package increases coupling.  That's a design choice.

Well, yes and no.  I argue that the color of a car is determined by the
characteristics of the car abstraction, so the declaration of (car)
color goes with the declaration of car.  For example, the factory that
manufactures the cars will only produce a limited number of possible
colors, and the abstraction should capture that feature of the domain.

> Its [the RM] primary intent, after all, was to unambiguously specify
> what the language is, not to prescribe how it should be used.

Well, that's a bit of a stretch.  I'd say just the opposite is true.
 
> Precedent, even long precedent, should not be the only criterion for
> chosing a coding style. I would think it's more important to base the
> choice on a well-thought out rationale.

Agreed.





  parent reply	other threads:[~1998-08-31  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           ` 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-30  0:00           ` Matthew Heaney
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                   ` Brian Rogoff
1998-07-29  0:00                     ` Matthew Heaney
1998-07-29  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                                 ` 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 [this message]
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                                                 ` 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-04  0:00                                               ` John G. Volan
1998-09-05  0:00                                                 ` Matthew Heaney
1998-09-05  0:00                                                   ` John G. Volan
1998-09-05  0:00                                               ` John G. Volan
1998-09-05  0:00                                               ` John G. Volan
1998-08-11  0:00                                       ` doylep
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                           ` 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 Norman H. Cohen
1998-07-28  0:00               ` Matthew Heaney
1998-07-28  0:00               ` Stephen Leake
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