Version 1.3 of ais/ai-00145.txt

Unformatted version of ais/ai-00145.txt version 1.3
Other versions for file ais/ai-00145.txt

!standard 03.05 (15)          99-08-31 AI95-00145/03
!standard 08.05.04 (05)
!standard A.01 (07)
!standard A.01 (09-10)
!reference RM95 3.5.1(10)
!reference RM95 3.5.4(9-10)
!reference RM95 3.5.9(13)
!reference RM95 4.5.1(3)
!reference RM95 4.5.2(7)
!reference RM95 4.5.2(9)
!reference RM95 4.5.3(2)
!reference RM95 4.5.3(4)
!reference RM95 4.5.4(2)
!reference RM95 4.5.5(2)
!reference RM95 4.5.5(14)
!reference RM95 4.5.6(2)
!reference RM95 A.1(15)
!status Corrigendum 2000 99-07-27
!class binding interpretation 96-10-07
!status WG9 approved 96-12-07
!status ARG Approved (subject to editorial review) 7-0-3 96-10-07
!status work item 96-09-08
!status received 96-06-06
!reference AI95-00107
!priority High
!difficulty Hard
!qualifier Omission
!subject Profile of predefined operators for scalar types
!summary
The italicized T shown in the definitions of predefined operators means:
- T'Base, for scalars
- the first subtype, for tagged types
- the type without any constraint, in other cases
The definitions of the operators in chapter 4 take precedence over those shown in A.1 in package Standard; for example, the "<" operator on type Boolean has parameters of subtype Boolean'Base, not Boolean.
If a renaming-as-body completes a declaration before the subprogram it declares is frozen, then the profile of the renaming-as-body need not be subtype-conformant with that of the renamed callable entity. The profile of such a renaming-as-body must instead be mode conformant with that of the renamed callable entity.
!question
4.5.2(8-9) says:
8 The ordering operators are predefined for every specific scalar type T, and for every discrete array type T, with the following specifications:
9 function "<" (Left, Right : T) return Boolean
...
where the T is in italics. Similar definitions are given throughout chapter 4 for other predefined operators. What is the meaning of this italicized type name notation? Presumably, it is intended to refer to the base subtype, at least in some cases.
However, the predefined operators shown in package Standard do not always use the base subtype:
function "<" (Left, Right : Boolean) return Boolean; -- A.1(7) function "<" (Left, Right : Integer'Base) return Boolean; -- A.1(15)
!recommendation
(See summary.)
!wording
(See summary.)
!discussion
Consider:
type T1 is range ...; type T2 is tagged ...; type T3(D: Integer) is tagged ...; type T4 is array(Integer range <>) of Integer; type T5 is array(Integer range 1..100) of Integer; type T6 is record ...;
The italicized notation refers to the following subtypes:
T1'Base T2 T3 T4 T5-without-the-constraint T6
respectively. Note that T2 and T6 are constrained, despite the fact that they have no constraint. Note also that in the case of T5, the subtype in question has no name in Ada, since the Base attribute is not defined for composite types.
The Boolean operators in A.1 are shown with the wrong subtypes -- Boolean'Base is correct.
8.5.4(5) says:
5 The profile of a renaming-as-body shall be subtype-conformant with that of the renamed callable entity, and shall conform fully to that of the declaration it completes. If the renaming-as-body completes that declaration before the subprogram it declares is frozen, the subprogram it declares takes its convention from the renamed subprogram; otherwise the convention of the renamed subprogram shall not be Intrinsic.
Consider:
package P is type T is private; private type T is new Integer'Base; end P; use P;
function Equals(X, Y: T) return Boolean; function Equals(X, Y: T) return Boolean renames "=";
Without this AI, the above renaming-as-body would be illegal, since it is not subtype conformant. However, if the full type declaration were "type T is new Integer;", then it would be legal. It is intolerable for the contents of the private part to affect the legality of a client in this way; therefore, we relax the rules for renamings-as-body that appear before the subprogram is frozen. Note that after the subprogram is frozen, one cannot use a renaming-as-body for a predefined operator, because it is intrinsic.
!corrigendum 8.05.04(05)
Replace the paragraph:
The profile of a renaming-as-body shall be subtype-conformant with that of the renamed callable entity, and shall conform fully to that of the declaration it completes. If the renaming-as-body completes that declaration before the subprogram it declares is frozen, the subprogram it declares takes its convention from the renamed subprogram; otherwise the convention of the renamed subprogram shall not be Intrinsic.
by:
The profile of a renaming-as-body shall conform fully to that of the declaration it completes. If the renaming-as-body completes that declaration before the subprogram it declares is frozen, the profile shall be mode-conformant with that of the renamed callable entity and the subprogram it declares takes its convention from the renamed subprogram; otherwise the profile shall be subtype-conformant with that of the renamed callable entity and the convention of the renamed subprogram shall not be Intrinsic.
!corrigendum A.01(7)
Replace the paragraph:
-- function "=" (Left, Right : Boolean) return Boolean; -- function "/=" (Left, Right : Boolean) return Boolean; -- function "<" (Left, Right : Boolean) return Boolean; -- function "<=" (Left, Right : Boolean) return Boolean; -- function ">" (Left, Right : Boolean) return Boolean; -- function ">=" (Left, Right : Boolean) return Boolean;
by:
-- function "=" (Left, Right : Boolean'Base) return Boolean; -- function "/=" (Left, Right : Boolean'Base) return Boolean; -- function "<" (Left, Right : Boolean'Base) return Boolean; -- function "<=" (Left, Right : Boolean'Base) return Boolean; -- function ">" (Left, Right : Boolean'Base) return Boolean; -- function ">=" (Left, Right : Boolean'Base) return Boolean;
!corrigendum A.01(9)
Replace the paragraph:
-- function "and" (Left, Right : Boolean) return Boolean; -- function "or" (Left, Right : Boolean) return Boolean; -- function "xor" (Left, Right : Boolean) return Boolean;
by:
-- function "and" (Left, Right : Boolean'Base) return Boolean'Base; -- function "or" (Left, Right : Boolean'Base) return Boolean'Base; -- function "xor" (Left, Right : Boolean'Base) return Boolean'Base;
!corrigendum A.01(10)
Replace the paragraph:
-- function "not" (Right : Boolean) return Boolean;
by:
-- function "not" (Right : Boolean'Base) return Boolean'Base;
!ACATS test
Construct a C-Test to check that renaming examples given here are legal and work as expected.
!appendix

!section 3.5(15)
!subject Profile of predefined operators for scalar types
!reference RM95 3.5(15)
!reference RM95 3.5.1(10)
!reference RM95 3.5.4(9-10)
!reference RM95 3.5.9(13)
!reference RM95 4.5.1(3)
!reference RM95 4.5.2(7)
!reference RM95 4.5.2(9)
!reference RM95 4.5.3(2)
!reference RM95 4.5.3(4)
!reference RM95 4.5.4(2)
!reference RM95 4.5.5(2)
!reference RM95 4.5.5(14)
!reference RM95 4.5.6(2)
!reference RM95 A.1(7)
!reference RM95 A.1(15)
!from Pascal Leroy 96-05-14
!reference 96-5553.a Pascal Leroy 96-5-14>>
!discussion

The predefined operators for various classes of types are defined throughout
section 4.5 (see above list of references, which may or may not be complete)
using declarations like (4.5.2(9)):

        function "<" (Left, Right : T) return Boolean;

We would like to understand the meaning of T in this specification, in the
case of scalar types.  The sentences which define these operators are worded
in terms of types (e.g., "specific scalar type T" in 4.5.2(8)) which tend to
indicate that the parameters are of the (unconstrained) type.  But what is
confusing is that the operators in the specification of package Standard use
sometimes the unconstrained base subtype (denoted by the attribute 'Base),
sometimes the first subtype:

        function "<" (Left, Right : Boolean) return Boolean; -- A.1(7)
        function "<" (Left, Right : Integer'Base) return Boolean; -- A.1(15)

There seems to be a difference between Boolean'Base and Boolean, and
Integer'Base and Integer: the semantics of attribute 'Base (3.5(15)) indicate
that it designates an _unconstrained_ subtype; on the other hand, a number of
scalar type declarations declare an unconstrained type and then a
_constrained_ first subtype.  This is the case for enumeration types
(3.5.1(10)), integer types (3.5.4(9-10)) and ordinary fixed point types
(3.5.9(13)).

An unconstrained subtype and the corresponding constrained first subtype are
not interchangeable whenever subtype conformance is required (6.3.1(17))
because an unconstrained subtype and a constrained one are not statically
matching (4.9.1(1-2)).  For instance, based on the declaration that appears in
A.1(7), the following renaming-as-body is legal:

        function LT (Left, Right : Boolean) return Boolean;
        function LT (Left, Right : Boolean) return Boolean renames "<";

but the following renaming-as-body is illegal:

        function LT (Left, Right : Integer) return Boolean;
        function LT (Left, Right : Integer) return Boolean renames "<";

We would expect the operators for Boolean declared in Standard to take
parameters of type Boolean'Base, as seems to be implied by various
declarations in 4.5.


_____________________________________________________________________
Pascal Leroy                                    +33.1.30.12.09.68
pleroy@rational.com                             +33.1.30.12.09.66 FAX


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

!section 3.5(15)
!subject Profile of predefined operators
!reference AI95-00145
!from Pascal Leroy 96-08-20
!reference 96-5634.a Pascal Leroy 96-8-21>>
!discussion

The referenced AI didn't trigger a lot of discussions, to say the least, so
let me try again...

There are two other issues related to the question of the profile of
predefined operators.  One is the interaction with the contract model, the
other is the fact that it is impossible to write a specification for the
predefined operators of composite types.

As an example of the first issue, look at the following example:

        generic
                type T is (<>);
        package P is
                function F (L, R : T) return Boolean;
        end P;

        package body P is
                function F (L, R : T'Base) return Boolean renames "="; -- (1)
                function F (L, R : T) return Boolean renames "="; -- (2)
        end P;

Which (if any) of the declarations (1) and (2) is legal?  If we follow 4.5,
which seems to say that the predefined operators are parameters of the
(unconstrained) type, then (1) is legal and (2) is illegal.  If we follow the
declarations given in the specification of Standard (A.1(7)) then we should
use (1) if T happens to be an enumeration type, and (2) if T happens to be an
integer type.  Of course, since the body of a generic is compiled in an
"assume-the-worst" manner, neither (1) nor (2) is legal.  This is a nuisance.

In the rest of this discussion I assume that the intended meaning is that of
4.5, and that A.1(7) is a mistake.

Consider now what happens if we change the formal part of P to be:

        generic
                type T is private
        package P is ...

Then we cannot even write (1), because the attribute 'Base is not available
for a composite type.  And of course (2) doesn't make sense:

        type T is array (1 .. 10) of Character;
        -- This type has an operator "=", but its profile is certainly not:
        -- function "=" (Left, Right : T) return Boolean;
        -- So we just cannot write that profile in Ada.  Sigh.

This situation is quite unpleasant, because a renaming-as-body would be very
useful in this case.

Clearly, similar difficulties arise with private types, at places that have
visibility over the private view:

        package P is
                type T is private;
                function Foo1 (L, R : T) return Boolean;
                function Foo1 (L, R : T) return Boolean renames "="; -- legal?
        private
                type T is new Natural;
                -- alternatively, type T is new Float;
        end

        function Foo2 (L, R : P.T) return Boolean;
        function Foo2 (L, R : P.T) return Boolean renames "="; -- legal?

Does he completion of type T affect the legality of the renaming-as-bodies in
these examples?

The language would be more useful if 'Base was allowed in a limited number of
circumstances for non-scalar types; in particular, it would be nice to be able
to write an Ada specification for the predefined operators.

_____________________________________________________________________
Pascal Leroy                                    +33.1.30.12.09.68
pleroy@rational.com                             +33.1.30.12.09.66 FAX

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

!section 4.5.2(7)
!subject Profile of predefined operators
!reference AI95-00145
!reference RM95-4.5.2(7-9)
!reference RM95-8.5.4(5)
!reference 96-5634.a Pascal Leroy 96-08-20
!from Tucker Taft 96-08-22
!reference 96-5638.a Tucker Taft 96-8-22>>
!discussion

> The referenced AI didn't trigger a lot of discussions, to say the least, so
> let me try again...
>
> There are two other issues related to the question of the profile of
> predefined operators.  One is the interaction with the contract model, the
> other is the fact that it is impossible to write a specification for the
> predefined operators of composite types.
>
> As an example of the first issue, look at the following example:
>
>       generic
>               type T is (<>);
>       package P is
>               function F (L, R : T) return Boolean;
>       end P;
>
>       package body P is
>               function F (L, R : T'Base) return Boolean renames "="; -- (1)
>               function F (L, R : T) return Boolean renames "="; -- (2)
>       end P;
>
> Which (if any) of the declarations (1) and (2) is legal?

Neither, since the predefined operators are of convention Intrinsic,
and renaming-as-body is not permitted for convention Intrinsic,
unless the renaming occurs before the freezing point of the corresponding
subprogram spec.  See 8.5.4(5).

> ... If we follow 4.5,
> which seems to say that the predefined operators are parameters of the
> (unconstrained) type, then (1) is legal and (2) is illegal.  If we follow the
> declarations given in the specification of Standard (A.1(7)) then we should
> use (1) if T happens to be an enumeration type, and (2) if T happens to be an
> integer type.

I presume you have your (1)'s and (2)'s inverted.  In any case, the
declarations given in A.1 for the operators of Boolean are wrong.
They should use Boolean'Base for the operands.  This is because
RM95 4.5.2(7-9) and elsewhere use an italicized "T" to give the
formal parameter subtype.  This notation is meant to be the
unconstrained subtype, which for scalars is denoted T'Base.

> ... Of course, since the body of a generic is compiled in an
> "assume-the-worst" manner, neither (1) nor (2) is legal.  This is a nuisance.
>
> In the rest of this discussion I assume that the intended meaning is that of
> 4.5, and that A.1(7) is a mistake.

Correct.

> Consider now what happens if we change the formal part of P to be:
>
>       generic
>               type T is private
>       package P is ...
>
> Then we cannot even write (1), because the attribute 'Base is not available
> for a composite type.  And of course (2) doesn't make sense:
>
>       type T is array (1 .. 10) of Character;
>       -- This type has an operator "=", but its profile is certainly not:
>       -- function "=" (Left, Right : T) return Boolean;
>       -- So we just cannot write that profile in Ada.  Sigh.
>
> This situation is quite unpleasant, because a renaming-as-body would be very
> useful in this case.

I'm not convinced about this, given that the "renaming-as-body" would
have to appear before the function being declared is frozen.

> Clearly, similar difficulties arise with private types, at places that have
> visibility over the private view:
>
>       package P is
>               type T is private;
>               function Foo1 (L, R : T) return Boolean;
>               function Foo1 (L, R : T) return Boolean renames "="; -- legal?

This is certainly a legitimate question, though again, since the
renaming-as-body has to occur before freezing, you could pretty much just
use the renaming-as-spec and avoid the issue.

I would say that the current rules make it illegal.  However, an alternative
approach would be to consider a renaming-as-body that appears before the
subprogram is frozen as equivalent to a renaming-as-spec, and hence the
above would be legal (since for renaming-as-spec, only the types and
modes, not the subtypes, matter).

In any case, I consider this a pathology, and would not welcome the
creation of an ACVC test for it.

>       private
>               type T is new Natural;
>               -- alternatively, type T is new Float;
>       end
>
>       function Foo2 (L, R : P.T) return Boolean;
>       function Foo2 (L, R : P.T) return Boolean renames "="; -- legal?
>
> Does he completion of type T affect the legality of the renaming-as-bodies in
> these examples?

I suspect current rules would indicate that it does.  However, that
violates the more general rule regarding "privacy" of private declarations,
so, as suggested above, we might want to further relax the restrictions on
"early" renaming-as-bodies, since we have already relaxed the rule on
convention Intrinsic for them.

> The language would be more useful if 'Base was allowed in a limited number of
> circumstances for non-scalar types; in particular, it would be nice to be able
> to write an Ada specification for the predefined operators.

I don't agree, given the existing restrictions on "late" renaming-as-body
applied to intrinsic-convention subprograms like the predefined operators,
as given in 8.5.4(5).

> Pascal Leroy                                    +33.1.30.12.09.68
> pleroy@rational.com                             +33.1.30.12.09.66 FAX

-Tuck

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

!section 4.5.2(7)
!subject Profile of predefined operators
!reference AI95-00145
!reference RM95-4.5.2(7-9)
!reference RM95-8.5.4(5)
!reference 96-5634.a Pascal Leroy 96-08-20
!from Pascal Leroy 96-08-23
!reference 96-5642.a Pascal Leroy 96-8-23>>
!discussion

> > Clearly, similar difficulties arise with private types, at places that
have
> > visibility over the private view:
> >
> >     package P is
> >             type T is private;
> >             function Foo1 (L, R : T) return Boolean;
> >             function Foo1 (L, R : T) return Boolean renames "="; -- legal?
>
> This is certainly a legitimate question, though again, since the
> renaming-as-body has to occur before freezing, you could pretty much just
> use the renaming-as-spec and avoid the issue.
>
> I would say that the current rules make it illegal.  However, an alternative
> approach would be to consider a renaming-as-body that appears before the
> subprogram is frozen as equivalent to a renaming-as-spec, and hence the
> above would be legal (since for renaming-as-spec, only the types and
> modes, not the subtypes, matter).

I agree with your idea of saying that an 'early' renaming-as-body should be
treated as a renaming-as-spec.  Such a rule would subsume the first half of
the second sentence of 8.5.4(5), which is nice because the current wording
smells too much like a special case.

> In any case, I consider this a pathology, and would not welcome the
> creation of an ACVC test for it.

Why?  Although it's certainly a cornercase, it would be good to ensure that
all compilers have the same interpretation, and there doesn't seem to be a big
implementation burden here.  At any rate, if we follow your suggestion and
change the rule, it should be checked by the ACVC.

> >     private
> >             type T is new Natural;
> >             -- alternatively, type T is new Float;
> >     end
> >
> >     function Foo2 (L, R : P.T) return Boolean;
> >     function Foo2 (L, R : P.T) return Boolean renames "="; -- legal?
> >
> > Does he completion of type T affect the legality of the renaming-as-bodies
> > in these examples?
>
> I suspect current rules would indicate that it does.  However, that
> violates the more general rule regarding "privacy" of private declarations,
> so, as suggested above, we might want to further relax the restrictions on
> "early" renaming-as-bodies, since we have already relaxed the rule on
> convention Intrinsic for them.

Looking through private parts is bad, so that seems like a pretty compelling
argument in favor of your proposed change.

> > The language would be more useful if 'Base was allowed in a limited number
> > of circumstances for non-scalar types; in particular, it would be nice to
> > be able to write an Ada specification for the predefined operators.
>
> I don't agree, given the existing restrictions on "late" renaming-as-body
> applied to intrinsic-convention subprograms like the predefined operators,
> as given in 8.5.4(5).

You are right wrt to renaming-as-body because of the rule about intrinsic
subprograms.  However, I am still uncomfortable with the fact that we cannot
write a specification for some of the predefined operators, because it seems
to cause problems whenever subtype conformance is required.

Our compiler currently rejects the following code fragment because it
complains that the overriding "=" is not subtype conformant with the inherited
"=" (3.9.2(10)):

        package P is
                type T is tagged private;
                function "=" (Left, Right : T) return Boolean;
        private
                type T is tagged null record;
        end P;

T is a constrained subtype as per 3.2(9), so as far as I understand, T is
different from the "T italic" used in 4.5.2(7).  And of course, I cannot
write:

         function "=" (Left, Right : T'Base) return Boolean;

I hope that there is flaw in my reasoning, because if it is correct, it looks
like we have a pretty severe problem...

Pascal

_____________________________________________________________________
Pascal Leroy                                    +33.1.30.12.09.68
pleroy@rational.com                             +33.1.30.12.09.66 FAX

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

!section 4.5.2(7)
!subject Profile of predefined operators
!reference AI95-00145
!reference RM95-4.5.2(7-9)
!reference RM95-8.5.4(5)
!reference 96-5634.a Pascal Leroy 96-08-20
!reference 96-5642.a Pascal Leroy 96-08-23
!from Tucker Taft 96-08-24
!reference 96-5643.a Tucker Taft 96-8-23>>
!discussion

> ...
> > In any case, I consider this a pathology, and would not welcome the
> > creation of an ACVC test for it.
>
> Why?  ...

What I mean is that in the absence of an AI on this topic, I do
not believe an ACVC should be written to require it to be illegal.
Certainly I agree with you that if an AI is written on this topic,
then we should back up whatever decision is made with an ACVC.

> ...
> You are right wrt to renaming-as-body because of the rule about intrinsic
> subprograms.  However, I am still uncomfortable with the fact that we cannot
> write a specification for some of the predefined operators, because it seems
> to cause problems whenever subtype conformance is required.

Where is subtype conformance a problem for you?

> Our compiler currently rejects the following code fragment because it
> complains that the overriding "=" is not subtype conformant with the inherited
> "=" (3.9.2(10)):

Your compiler is wrong in this case (see below).

>       package P is
>               type T is tagged private;
>               function "=" (Left, Right : T) return Boolean;
>       private
>               type T is tagged null record;
>       end P;
>
> T is a constrained subtype as per 3.2(9), so as far as I understand, T is
> different from the "T italic" used in 4.5.2(7).

T is considered "constrained" by 3.2(9) only in that there is no
constraint defined for the type.  "T italic" is intended to be
the subtype without any constraint, but that doesn't make it any
different in this case.

Furthermore, if you look at 3.4(20), implicitly declared inherited
subprograms of a tagged type use the first subtype, rather than "T'Base"
or whatever in their profile, precisely to avoid running afoul of the
subtype conformance requirement when overriding them.   This coupled with
6.3.1(7) which indicates that all implicitly declared subprograms of
tagged types escape "intrinsic"ness (again, to allow subtype-conformant
overriding), would suggest that a rule like 3.4(20) should apply
to all implicitly declared subprograms of a tagged type, including
predefined "=".

> write:
>
>        function "=" (Left, Right : T'Base) return Boolean;
>
> I hope that there is flaw in my reasoning, because if it is correct, it looks
> like we have a pretty severe problem...

I think your logic is a bit "flawed" with respect to the meaning
of "T italic" when there is no constraint defined for the type.
However, there is a bit of a problem in the wording of 3.4(20) as written
since it doesn't apply to predefined "=".  We should probably revise
3.4(20) to simply say that all the implicitly declared primitives of
a tagged type use the first subtype in their profile.  This would
then cover the case of the "=" for NT in:

   type NT is new T(Discrim => 3) with null record;

which is not currently covered by 3.4(20) (since "=" is not inherited,
but is rather reconstructed anew for a record extension, per the last
sentence of 3.4(17)).

It also wouldn't hurt to have an AI that defines more clearly the meaning
of "T italic".  Given the intent of 3.4(20), it might be best to define
"T italic" for a tagged type to be the first subtype, while for all other
types, it would be the subtype with a "null" constraint, if one is defined
for the type.  This would probably be the definition for T'Base as well,
if it were (re)extended to cover non-scalar types.

[Historical aside: we dropped T'Base for composite types because it was hard
to define it for a case of a discriminated derived type with a
constrained first subtype.  It would seem legitimate to "squeeze" out
the discriminant completely in a "packed" representation for such a type.
If you then declared a value of the T'Base subtype, what would be its
representation?  What would be T'Base'Size in such a case?

Also in Ada 83, the T'Base for a derived type was defined in terms of
the T'Base for the parent type.  In the case of a record extension that
constrained the discriminants of the parent type, and then added a new set of
discriminants of its own, defining T'Base for the derived type in terms
of T'Base for the parent type doesn't work very well.

Both of these problems are admittedly obscure, but they were enough
for us to eliminate T'Base for non-scalar types given the complexity
of fully defining it.  Perhaps the headaches are coming back with
"T italic" but at least it is somewhat better in that the user has no
explicit notation for referring to "T italic" in the bizarre cases.
Of course your whole complaint is that the user has no explicit notation
for referring to "T italic" in renaming-as-body and overriding, but I hope
we can solve that without having to bring back T'Base.]

> Pascal Leroy                                    +33.1.30.12.09.68
> pleroy@rational.com                             +33.1.30.12.09.66 FAX

-Tucker Taft

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

!section 3.5(15)
!subject Profile of predefined operators
!reference AI95-00145
!reference 96-5634.a Pascal Leroy 96-8-21
!from Bob Duff
!reference 96-5694.a Robert A Duff 96-9-8>>
!discussion

Pascal gave this example:

> Clearly, similar difficulties arise with private types, at places that have
> visibility over the private view:
>
>       package P is
>               type T is private;
>               function Foo1 (L, R : T) return Boolean;
>               function Foo1 (L, R : T) return Boolean renames "="; -- legal?
>       private
>               type T is new Natural;
>               -- alternatively, type T is new Float;
>       end
>
>       function Foo2 (L, R : P.T) return Boolean;
>       function Foo2 (L, R : P.T) return Boolean renames "="; -- legal?
>
> Does he completion of type T affect the legality of the renaming-as-bodies in
> these examples?

And Tucker answered:

> I suspect current rules would indicate that it does.

I don't understand.  Could one of you two explain why?

The renaming-as-body for Foo2 looks legal to me, no matter what's in the
private part.

It seems to me that immediately after the private type decl, there is an
implicit decl that looks like this:

    function "="(Left, Right: T) return Boolean;

And immediately after the full type decl, there is another implicit decl
that looks like this:

    function "="(Left, Right: T'Base) return Boolean;

(This is following Tucker's explanation for what the italicized T is
supposed to mean.  The private view is composite, non-tagged, so "the
type without a constraint" is just the first subtype, namely T, which is
constrained.  For the full view, "the type without a constraint" is
T'Base.)

The client can't see the private "=", so how can it affect the legality
of Foo2?

- Bob

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

!section 3.5(15)
!subject Profile of predefined operators
!reference AI95-00145
!reference 96-5634.a Pascal Leroy 96-8-21
!reference as: 96-5694.a Robert A Duff 96-9-8
!from Pascal Leroy
!reference 96-5695.a Pascal Leroy 96-9-9>>
!discussion

> > I suspect current rules would indicate that it does.
>
> I don't understand.  Could one of you two explain why?

The question that we were asking was basically this: in determining the
profile of the predefined "=", do you look at the completion of private types?

Tucker said that he thought the current rules require to do so.  Note that he
didn't mention a particular verse of the RM, so this sounded more like gut
feeling than like exegesis.  He then started to develop an interpretation of
"T italic" which would (hopefully) avoid to look at private parts.

> The renaming-as-body for Foo2 looks legal to me, no matter what's in the
> private part.
>
> It seems to me that immediately after the private type decl, there is an
> implicit decl that looks like this:
>
>     function "="(Left, Right: T) return Boolean;
>
> And immediately after the full type decl, there is another implicit decl
> that looks like this:
>
>     function "="(Left, Right: T'Base) return Boolean;
>
> (This is following Tucker's explanation for what the italicized T is
> supposed to mean.  The private view is composite, non-tagged, so "the
> type without a constraint" is just the first subtype, namely T, which is
> constrained.  For the full view, "the type without a constraint" is
> T'Base.)

Ok, but now you are using Tucker's interpretation of "T italic", not the
wording of the RM (which is quite unclear btw).

I think that you are pointing to a problem in Tucker's interpretation, though.
 You notice that there are two "=", one declared in the visible part and the
other in the private part (after the completion of the type).  But for types
for which T and T'Base are different (e.g. integer and enum types), these two
subprograms are not subtype-conformant.  So surely one is not the completion
of the other.  But then they are homographs, because they are indeed
type-conformant, and therefore they are illegal.  Unfortunate, isn't it?

Pascal

_____________________________________________________________________
Pascal Leroy                                    +33.1.30.12.09.68
pleroy@rational.com                             +33.1.30.12.09.66 FAX

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

Questions? Ask the ACAA Technical Agent