Version 1.1 of acs/ac-00130.txt

Unformatted version of acs/ac-00130.txt version 1.1
Other versions for file acs/ac-00130.txt

!standard 8.4(8)          06-05-11 AC95-00130/01
!class confirmation 06-05-11
!status received no action 06-05-11
!status received 06-04-19
!subject Use type doesn't give you enumeration literals
!summary
!appendix

!reference 8.4(8)
!from Adam Beneschan 06-04-19

I'm sure this issue has been discussed at some point, but I couldn't
find any reference to it in the AI's or AC's.  I wish I had thought of
it a couple years ago, when a change to Ada 200Y could still be
considered, but I'm thinking of it now because I ran into a problem
with it today.

My problem was that I had a package that declared an enumeration type:

   package Pak1 is
       ...
       type Enum_Type is (E1, E2, E3, E4, ..., E_One_Jillion);


(OK, in reality there were a couple dozen literals, not a jillion.)
The body of Pak1 made references to many of these enumeration
literals.

Later, I decided it was necessary to move this type to another
package, Pak2.  Since Pak1's body used direct (not expanded) names to
refer to all the enumeration literals, there arose the problem of how
to make these names visible so that all the references to them
wouldn't have to be changed.  Writing a jillion renaming declarations
in Pak1 certainly isn't appealing, and you'd possibly have to update
this list if a new enumeration literal or fifty got added to the
type.

I could certainly change the declaration of Enum_Type to

   package Pak1 is
       ...
       subtype Enum_Type is Pak2.Enum_Type;
       use type Enum_Type;  -- either here or in Pak1's body


Of course, we've known since Ada 83 that this was not a full solution
since it made the type name visible but not the operations of the
type.  That's why USE TYPE was added in Ada 95.  But it doesn't help
here, because USE TYPE gives you only those operations defined by
operator symbols.  It seems like it ought to give you enumeration
literals too, but it doesn't.  Although I can understand why you
wouldn't want to make all primitive subprograms visible, enumeration
literals just seem different, probably because conceptually they're
not really functions even though the language treats them that way.

Suggestion (for Ada 201Z): It's probably not a good idea at this point
to change the semantics of the existing USE TYPE syntax so that it
made enumeration literals visible; but how about adding a syntax like:

       use type Enum_Type with (<>);

to indicate that enumeration literals are also made potentially
use-visible, in the same way primitive operators are by 8.4(8).

****************************************************************

From: Tucker Taft
Date: Wednesday, April 19, 2006  3:13 PM

When "use type" was designed, we debated this seriously.
Ultimately we decided to only make operators visible,
since these are guaranteed to be overloadable.  The
problem with making enumeration literals visible is
that they could conflict with non-overloadables (such
as object names), which ends up hiding one or both
of them.  The other reason is why stop at enumeration
literals?  Why not all primitive operations?  Or all
parameterless primitive functions?  Operators were a
well defined set, but once you get into non-operator
primitives, it is hard to make a clear distinction.

Bottom line is you will have to use a "use <package>" clause
if you want to make enumeration literals visible,
and there you already have come to expect some issues
with identifiers canceling out.

****************************************************************

From: Tucker Taft
Date: Wednesday, April 19, 2006  3:15 PM

P.S. Note that in Ada 95, we eliminated one reason to need
direct visibility on enumeration literals, namely to
be able to use string literals with a user-defined
character literals.  In Ada 83, you needed to "use"
the package where the user-defined character type was
defined to be able to use string literals for an array-of-char
type.

****************************************************************

From: Adam Beneschan
Date: Wednesday, April 19, 2006  3:36 PM

> When "use type" was designed, we debated this seriously.
> Ultimately we decided to only make operators visible,
> since these are guaranteed to be overloadable.  The
> problem with making enumeration literals visible is
> that they could conflict with non-overloadables (such
> as object names), which ends up hiding one or both
> of them.  The other reason is why stop at enumeration
> literals?  Why not all primitive operations?  Or all
> parameterless primitive functions?  Operators were a
> well defined set, but once you get into non-operator
> primitives, it is hard to make a clear distinction.

But aren't enumeration literals a well-defined set also?  (Enumeration
literals are *not* just like other parameterless functions.  They're
static functions, and you can use them in CASE statements and in other
places where you can use a constant but not a function call.)  Anyway,
I don't really understand this part of the argument.

> Bottom line is you will have to use a "use <package>" clause
> if you want to make enumeration literals visible,
> and there you already have come to expect some issues
> with identifiers canceling out.

Which is one of the reasons I suggested a new syntax (rather than
suggesting that we change the way USE TYPE works).  Presumably,
someone who uses this syntax is going to be just as aware of the same
issues as with "use <package>".

Of course, using "use <package>" isn't an acceptable alternative if it
results in making other things visible that you don't want
visible---which was another reason USE TYPE was added.  (Although I
suppose it's conceivable to put the enumeration type in its own little
subpackage and USE that.)

****************************************************************

From: Tucker Taft
Date: Wednesday, April 19, 2006  4:19 PM

> But aren't enumeration literals a well-defined set also?  (Enumeration
> literals are *not* just like other parameterless functions.  They're
> static functions, and you can use them in CASE statements and in other
> places where you can use a constant but not a function call.)  Anyway,
> I don't really understand this part of the argument.

They are not really very distinct from a visibility
point of view.  And suppose you wanted to provide
abbreviations for certain long enumeration literals.  E.g.:

    type States is (Alabama, ..., Wyoming);

    function AL return States renames Alabama;
      ...
    function WY return States renames Wyoming;


These abbreviations have many of the properties
of enumeration literals you mentioned.  Would
you or wouldn't you want those made directly
visible?

In any case, I am sympathetic with your desire.
But you asked for a rationale, and the above is
what we had at the time.  I certainly could
see adding a version of "use" that made
all primitives directly visible.  Perhaps something
like "use all type T;"  But I suspect many people
would say "just use the *?$!# package and don't be
such a sissy" or something similarly sensitive... ;-)

****************************************************************


Questions? Ask the ACAA Technical Agent