!standard 03.05 (15) 00-07-13 AI95-00145/04 !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 Error !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 section 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) say: The ordering operators are predefined for every specific scalar type T, and for every discrete array type T, with the following specifications: function "<" (Left, Right : T) return Boolean ... where the T is in italics. Similar definitions are given throughout section 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 the following type declarations, where the comments show the subtypes associated with the italicized notation in section 4: <> type T1 is range ...; -- T1'Base type T2 is tagged ...; -- T2 type T3(D: Integer) is tagged ...; -- T3 type T4 is array(Integer range <>) of Integer; -- T4 type T5 is array(Integer range 1..100) of Integer; -- T5-without-the-constraint type T6 is record ...; -- T6 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. Furthermore, 8.5.4(5) says: 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. However, 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 ruling, 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) @drepl 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. @dby 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) @drepl @xcode< -- @b "=" (Left, Right : Boolean) @b<@b> Boolean; -- @b "/=" (Left, Right : Boolean) @b Boolean; -- @b "<" (Left, Right : Boolean) @b Boolean; -- @b "<=" (Left, Right : Boolean) @b Boolean; -- @b "@>" (Left, Right : Boolean) @b Boolean; -- @b "@>=" (Left, Right : Boolean) @b Boolean;> @dby @xcode< -- @b "=" (Left, Right : Boolean'Base) @b Boolean; -- @b "/=" (Left, Right : Boolean'Base) @b Boolean; -- @b "<" (Left, Right : Boolean'Base) @b Boolean; -- @b "<=" (Left, Right : Boolean'Base) @b Boolean; -- @b "@>" (Left, Right : Boolean'Base) @b Boolean; -- @b "@>=" (Left, Right : Boolean'Base) @b Boolean;> !corrigendum A.01(9) @drepl @xcode< -- @b "and" (Left, Right : Boolean) @b Boolean; -- @b "or" (Left, Right : Boolean) @b Boolean; -- @b "xor" (Left, Right : Boolean) @b Boolean;> @dby @xcode< -- @b "and" (Left, Right : Boolean'Base) @b Boolean'Base; -- @b "or" (Left, Right : Boolean'Base) @b Boolean'Base; -- @b "xor" (Left, Right : Boolean'Base) @b Boolean'Base;> !corrigendum A.01(10) @drepl @xcode< -- @b "not" (Right : Boolean) @b Boolean;> @dby @xcode< -- @b "not" (Right : Boolean'Base) @b Boolean'Base;> !ACATS test C854003 checks that a renames-as-body used before the subprogram is frozen only requires mode conformance. (Test, 8-0-0, ARG Letter Ballot, February 2001). Create a C-Test to check that the predefined boolean operators have the parameter type Boolean'Base. (No Test, 4-3-1 (2/3rd majority required, but not achieved), ARG Letter Ballot, February 2001). It was felt that it was unlikely that compilers would get this wrong. !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 **************************************************************** From: Bob Duff Sent: Monday, June 6, 2005 12:37 PM I'm using draft 11.8 of the [A]ARM. 4.5.1(3): 3 function "and"(Left, Right : T) return T function "or" (Left, Right : T) return T function "xor"(Left, Right : T) return T 3.a/2 This paragraph was deleted.To be honest: {AI95-00145-01} 3.b/2 Ramification: {AI95-00145-01} For these operators, we are talking about the type itself, and not some subtype of it. Since it's possible that the type itself cannot be named, we denote the type with an italicized T. This applies to the italicized T in many other predefined operators and attributes as well.{T (italicized)} 3.c/2 {AI95-00145-01} In many cases, there is a subtype with the correct properties available. The italicized T means: The old version of 3.a says: 3.a To be honest: For predefined operators, the parameter and result subtypes shown as T are actually the unconstrained subtype of the type. I don't understand this change. In particular: "it's possible that the type itself cannot be named". But types can never be named in Ada -- only subtypes can. **************************************************************** From: Tucker Taft Sent: Monday, June 6, 2005 7:15 PM I agree, this new wording seems bogus. The "type itself" doesn't mean anything. Formal parameters always have a subtype. I think the issue is that we are not necessarily talking about the *first* subtype, but rather perhaps some anonymous unconstrained subtype. **************************************************************** From: Randy Brukardt Sent: Monday, June 6, 2005 9:55 PM ... > The old version of 3.a says: > > 3.a To be honest: For predefined operators, the parameter and result > subtypes shown as T are actually the unconstrained subtype of the > type. > > I don't understand this change. "unconstrained subtype" is not correct; this could be a constrained type if it has no constraints. In any case, I was trying to summarize AI-145, which is trying to explain what these things mean. Since reviewers (including you, I think) seem to have been confused about the meanings of these things, I figured a more complete explanation was needed. The ARG decided that this didn't need a wording change, so "To be honest" seems the wrong heading. > In particular: "it's possible that the type itself cannot be named". > But types can never be named in Ada -- only subtypes can. True enough. It probably should say something to the effect that an appropriate subtype of the type cannot be named. But I guess the bigger problem is occurs if you insist that this means some sort of subtype (especially other than the first subtype). Subtypes don't appear out of thin air! I can justify in my mind that the predefined operators work on the type directly, but if they're supposed to work on some subtype, we'd need to clearly define that subtype. Especially if it is not the obvious one (the first subtype). Ergo, we do need a wording change to the Standard. That is, we should define "base subtype" or something like that to mean what is given in the bullets in 4.5.1(3.d-3.f). And then we should explicitly say that all of these operations have parameters and results of the appropriate base subtypes. (Both in Section 4 and 13 and anywhere else that this notation is used.) Tucker wrote: > I agree, this new wording seems bogus. The "type itself" > doesn't mean anything. Formal parameters always > have a subtype. I think the issue is that we > are not necessarily talking about the *first* subtype, > but rather perhaps some anonymous unconstrained > subtype. I don't think we can base the language on "rather perhaps"! And we can't say that they *are* unconstrained (because that might not be true). And I can't justify this as a "ramification" if we are talking about some magical subtype never defined or described by the language. "type without any subtype" makes sense, but not "subtype from the following bulleted list"! **************************************************************** From: Pascal Leroy Sent: Tuesday, June 7, 2005 4:20 PM > > In particular: "it's possible that the type itself cannot be named". > > But types can never be named in Ada -- only subtypes can. > > True enough. It probably should say something to the effect > that an appropriate subtype of the type cannot be named. Agreed. > But I guess the bigger problem is occurs if you insist that > this means some sort of subtype (especially other than the > first subtype). Subtypes don't appear out of thin air! I can > justify in my mind that the predefined operators work on the > type directly, but if they're supposed to work on some > subtype, we'd need to clearly define that subtype. Especially > if it is not the obvious one (the first subtype). Ergo, we do > need a wording change to the Standard. > > That is, we should define "base subtype" or something like > that to mean what is given in the bullets in 4.5.1(3.d-3.f). > And then we should explicitly say that all of these > operations have parameters and results of the appropriate > base subtypes. (Both in Section 4 and 13 and anywhere else > that this notation is used.) Please don't go there. This is an extremely unimportant issue, and we decided when AI 145 was discussed that it was not necessary to change any wording. There is no reason to revisit this decision now. This is only an AARM note anyway, the purpose of which is to clarify the meaning of the italicized T for language lawyers and compiler writers. No point in being overly pedantic. Btw, in this AARM note, you are writing "italized"; the correct spelling is "italicized". ****************************************************************