Randy Brukardt wrote:

> I agree with the position number is the important thing.
>
> Indeed, the restriction on the ordering of the representations should be 
> eliminated, as it only helps out a single rarely used operation (">") and
> makes it harder to define proper ranges of values in some cases. (I think 
> someone else said this but I can't find it.) [GNAT has a pragma to eliminate
> the use of ">" for enumerations, so it must not be wanted fairly often - and 
> if not wanted, not used either.]
> The only necessary requirement is that the mapping of representations to 
> positions is unique.
>
> Enumeration representations are useful only for interfacing, and it's 
> unlikely that anything very complicated is going to be done with them.
> (Mostly, just assigning and reading values.) Ergo, a simple implementation 
> that uses position numbers for any operation beyond assignment is good enough.

I think it would be OK if the rule regarding order in the representations was 
eliminated, but if it were, I would for some reason have expected the ">" and 
"<" operations to evaluate based on the position values, rather than the 
representation values.

Representation values usually only come into play when crossing an interface 
(such as during streaming, file IO, and unchecked conversions, and language 
boundaries such as Ada/C imports and exports)

Either way, it would need to be clearly defined which was used, if that 
restriction were removed.

The very practical use for those operators is the ability to use them as keys 
in containers like ordered maps, and so on.
In those cases, the actual order isn't important, just that there -is- an order 
that makes them sortable.  That is very important.

Even for keys made of records, the sortable nature of the record elements 
(which may include enums) is helpful.
It would be less desirable to have to use the image of an enum and sort by the 
string representation just to be able to provide a "<" operator to an ordered 
map.

Joshua Fletcher
613-721-4405


-----Original Message-----
From: Randy Brukardt <[email protected]>
Sent: Tuesday, December 3, 2019 7:41 PM
To: 'Ada-Comment List' <[email protected]>
Subject: Re: [Ada-Comment] Easier Ada enumeration value assignments

Daisy picking a few thoughts to comment on:

Jean-Pierre Rosen writes:

...
> I think it is a nice feature to have a clear separation between high
> level semantics and low level semantics. The 'Pos is the position in
> the definition and has nothing to do with internal representation.

I agree with the position number is the important thing.

Indeed, the restriction on the ordering of the representations should be 
eliminated, as it only helps out a single rarely used operation (">") and makes 
it harder to define proper ranges of values in some cases. (I think someone 
else said this but I can't find it.) [GNAT has a pragma to eliminate the use of 
">" for enumerations, so it must not be wanted fairly often - and if not 
wanted, not used either.] The only necessary requirement is that the mapping of 
representations to positions is unique.

Enumeration representations are useful only for interfacing, and it's unlikely 
that anything very complicated is going to be done with them.
(Mostly, just assigning and reading values.) Ergo, a simple implementation that 
uses position numbers for any operation beyond assignment is good enough.

> Otherwise, you fall into the C++ model where enums are just a kind of
> integer number. Moreover, if the renaming-as-function is a bit weired,
> just use a static constant to provide another name to a literal, i.e.
>   B : constant Enum := A;

A constant is not overloadable, however, and that means it is dangerous to use 
with "use" clauses. A function is overloadable, and is safe to use with use 
clauses. Note that the function is made visible by "use all type" if it is in 
the same package, but the constant is not. Thus, the function form is perferred.

Most of the time, it doesn't matter, but it can.

> > The current Ada model implies that somehow the internal codes are a
> > "minor" representation issue, when in fact, in many embedded-system
> > contexts, the internal codes are fundamental to the meaning of the
> > type.
> The model is to be able to keep the high level meaning independent
> from the low level specification. If you go that way, you could as
> well embed the position of record components into the definition of
> the record type, etc.

This principle (if it ever existed), was abandoned by the introduction of 
aspect specifications in Ada 2012. One can specify the size, alignment, and 
other representation properties directly in a type defintion. How does this 
differ??

Indeed, Tucker's original proposal did include embedding the position of 
components. We only dropped that due to verbosity, not because it wasn't a good 
idea:

    type Some_Record is record
       A : Natural with Position => 0, First_Bit => 0, Last_Bit => 15;
       B : Character with Position => 2, First_Bit => 0, Last_Bit => 7;
    end record;

Note that this isn't legal in Ada 2012 because Position, First_Bit, and 
Last_Bit aren't specifiable attributes (an aspect clause is allowed on 
component declarations). One could easily imagine a more compact form in some 
future version of Ada.

We didn't allow aspect specifications on enumeration literals, but that argubly 
was a mistake (there are very few kinds of declarations that don't allow them). 
That provides an alternative proposal:

    type My_Enum is (
        A with Rep_Value => 1,
        B with Rep_Value => 11,
        C with Rep_Value => 21);

Again, rather verbose, but it fits the existing model very well.

Joshua Fletcher wrote:

>I'm not sure of any practical advantage using the function rename over
>a static constant. Examples I've seen have the function rename in a
>different package from the original enum definition, and I'm still not
>sure what that provides over a static constant.

I described that above. A function is overloadable, and a primitive operation 
of the type if declared with the type. A static constant is neither. Thus the 
constant hides all other declarations and potentially makes trouble when 
package use clauses are involved. Since the functions are primitive, they will 
be made visible with the substantially safer "use all type" while a constant 
would not be.

In my experience, enumeration literals tend to pop up in multiple types (there 
are number of such occurrences in the Janus/Ada compiler source code, and in 
Claw). So the fact that they are overloadable and values for different types do 
not conflict is very important.

...
>One of the advantages of having distinct definitions of the
>representation from the type definition itself is that derived types
>can have distinct representations from their base type.
...
>That is a neat feature of the language.  It may not be used very often,
>but

>it can be useful.

Sadly, it is a nearly useless feature of the language. If one declares types 
and operations together (as anyone steeped in object-based programming would), 
a derivation with a different representation is going to be illegal by 
13.1(10). That means almost all useful cases of derivation are going to illegal 
unless you use a suboptimal code organization.

I view untagged derived types as nearly a pathology because of this effect:
the useful cases are illegal or should have been done another way.

...
>Another useful feature would be a way to derive extended enums,
>although
I'm
>sure this idea has been proposed and discussed before...

That was AI95-00261-1. It was abandoned in part because of the lack of good 
usage examples. (I was the one that proposed it and worked out the details.) 
Most of the cases simply raise an exception and thus would have to be manually 
rewritten to do anything useful. But if you are going to rewrite the bodies of 
all of the operations, you can just as well use a new type with a conversion 
function.

...
>> you lose 'Image and 'Value,
>????

Remember that 'Image of an enumeration is the name of the literal. While the 
'Image of a modular value is an integer literal. So switching to a modular 
representation eliminates the "nice" 'Image of an enumeration type, and the 
matching 'Value. For Ada 202x, you could manually create a Put_Image to 
redefine the modular type's Image to be the names of the constants. But that's 
a lot of work, and there is no matching capability for 'Value.

The only advantage of the modular representation is the ability to use the 
static constants in static math expressions. That's not much in most cases.

...
>I don't think we should be providing "Alt_Names" in the definition of
>an
enum;
>I'm not sure what that provides practically, beyond defining equivalent
>constants.

Functions, not constants. Overloading is important (I'd say critical) for 
enumeration literals.

Argubly, one should *always* use functions in preference to constants
*unless* they need to be static for math purposes. And, yes, it's a bug in Ada 
(dating back to Ada 83) that objects and exceptions aren't overloadable.
But changing would be incompatible in the worst possible way (legal code 
changing meaning in a newer Ada), so changing that is not an option for Ada (it 
will have to wait for an Ada successor language).

>It doesn't put all equivalent names on equal footing, since one is the
>main

>name for the value, and the others are alternate.

That's not possible regardless of syntax. Enum'Image has to have a well-defined 
result, and that is going to be the primary name. There is no way for 'Image to 
return whatever name you originally stored, if they have the same 
representation. How could it tell the difference??

                            Randy.





________________________________________________________

You have received this message because you subscribed to the Ada-Comment 
mailing list. To leave the Ada-Comment list, send an email with 'leave 
Ada-Comment' in the body to [email protected]. For help on the other 
commands available, send 'help Ada-Comment' to the same address.
Problems? Send mail to [email protected]. This list is operated by the Ada 
Resource Association, Inc., PO Box 8685, New York NY 10116-8685.




“This message and/or attachments may include information subject to GD 
Corporate Policies 07-103 and 07-105 and is intended to be accessed only by 
authorized recipients. Use, storage and transmission are governed by General 
Dynamics and its policies. Contractual restrictions apply to third parties. 
Recipients should refer to the policies or contract to determine proper 
handling. Unauthorized review, use, disclosure or distribution is prohibited. 
If you are not an intended recipient, please contact the sender and destroy all 
copies of the original message.”

Reply via email to