!standard 03.07 (08) 99-08-31 AI95-00098/02 !standard 12.05 (10) !class binding interpretation 95-10-12 !status Corrigendum 2000 99-05-25 !status WG9 Approved 97-11-14 !status ARG approved (6-0-1) subject to editorial review 97-04-11 !status work item 95-10-13 !status received 95-10-12 !priority Medium !difficulty Medium !qualifier Omission !subject unknown_discriminant_parts on generic formal types !summary A generic formal type must not have an unknown_discriminant_part, unless the type is a composite non-array type. !question 12.5(10) (a NOTE) says that "A discriminant_part is allowed only for certain kinds of types, and therefore only for certain kinds of generic formal types. See 3.7." Unfortunately, the rule in 3.7(8) only applies to known_discriminant_parts. 3.7 does not contain any rule restricting the usage of unknown_discriminant_parts. Various syntax rules usually do the job, but for generic formal types, the syntax allows unknown_discriminant_parts. Therefore, are the following legal? (No.) generic type Disc (<>) is (<>); -- Illegal! type Flt (<>) is Digits (<>); -- Illegal! type Str (<>) is new String; -- Illegal! procedure .... !recommendation (See summary.) !wording Remove the first occurrence of "known_" from 3.7(8). Change ";" to ".". The result is: 8 A discriminant_part is only permitted in a declaration for a composite type that is not an array type (this includes generic formal types). A type declared with a known_discriminant_part is called a discriminated type, as is a type that inherits (known) discriminants. !discussion The intent is that elementary and array types cannot have discriminant parts (known or unknown). !corrigendum 3.07(8) @drepl A @fa is only permitted in a declaration for a composite type that is not an array type (this includes generic formal types); a type declared with a @fa is called a @i type, as is a type that inherits (known) discriminants. @dby A @fa is only permitted in a declaration for a composite type that is not an array type (this includes generic formal types). A type declared with a @fa is called a @i type, as is a type that inherits (known) discriminants. !ACATS test A B-Test is needed to check that unknown discriminant parts cannot be given on formal types that don't meet the revised wording. !appendix !section 12.5(08) !subject Unknown_Discriminant parts on generic formal types. !reference RM95-12.5(8) !reference RM95-3.7(8) !from Randy Brukardt 95-09-28 <> !discussion 12.5(8) (a note) says that "A discriminant_part is allowed only for certain kinds of types, and therefore only for certain kinds of generic formal types. See 3.7." Unfortunately, the rule in 3.7(8) only applies to known_discriminant_parts. 3.7 does not contain any rule restricting the usage of unknown_discriminant_parts. Various syntax rules usually do the job, but for generic formal types, the syntax allows unknown_discriminant_parts. Therefore, are the following legal? If not, why not? Generic Type Disc (<>) Is (<>); Type Flt (<>) Is Digits (<>); Type Str (<>) Is New String; Procedure .... **************************************************************** !section 12.5(08) !subject Unknown_Discriminant parts on generic formal types. !reference RM95-12.5(8) !reference RM95-3.3(23) !reference RM95-3.7(1) !reference RM95-3.7(8) !reference 95-5307.a rbrukardt@BIX.com 95-9-29 !from Gary Dismukes 95-09-30 !reference as: 95-5309.a Gary Dismukes 95-9-30>> !discussion > 12.5(8) (a note) says that "A discriminant_part is allowed only for certain > kinds of types, and therefore only for certain kinds of generic formal types. > See 3.7." > > Unfortunately, the rule in 3.7(8) only applies to known_discriminant_parts. > 3.7 does not contain any rule restricting the usage of > unknown_discriminant_parts. Coincidentally, I came across this definitional gap myself just a few days ago. There doesn't seem to be a rule disallowing an unknown_ discriminant_part for arbitrary kinds of formal types. However... > Various syntax rules usually do the job, but for generic formal types, > the syntax allows unknown_discriminant_parts. Therefore, are the following > legal? If not, why not? > > Generic > Type Disc (<>) Is (<>); > Type Flt (<>) Is Digits (<>); > Type Str (<>) Is New String; > Procedure .... I don't believe an unknown_discriminant_part should be permitted for these, at least in the first two of the above examples. There is strong evidence that the intent is that elementary types cannot have unknown discriminants. In 3.3(23) we have a definition of indefinite subtype followed by "otherwise the subtype is a definite subtype (all elementary subtypes are definite subtypes)." Since types Disc and Flt are elementary subtypes but also are indefinite subtypes (since they have unknown discriminants), that's in contradiction to the parenthetical assertion. There also wouldn't seem to be much practical use for such types, even if they were allowed. In the case of a type such as Str it's somewhat less clear to me whether this should be disallowed. I don't see any big problem with allowing it and it might conceivably be of some use (well probably marginal use if any), but it doesn't seem worth any special rules. Incidentally, it turns out there's an ACVC test (bc50001) that gives (<>) on a formal derived access type and a formal derived string type. This test is of course invalid if either of these uses of unknown_discriminant_part is deemed illegal. So I would suggest there should be a rule that states that an unknown_discriminant_part is only allowed for (at most) a formal type that is a composite type. Actually, it seems simpler to me and more sensible to only allow an unknown_discriminant_part for formal private types. I'm not sure whether that disallows any useful cases, but at the moment I can't see any real benefit to allowing (<>) for the other cases of composite formal types. In fact, since 3.7(1) discusses unknown_discriminant_parts specifically in the context of partial views, this suggests that the intent is that they can only be given for partial views. That's what makes the most sense to me. Perhaps a restriction against giving (<>) for nonprivate formal types is somehow a consequence of other rules, but since we're both missing it, that suggests that at least a clarification is in order. -- Gary **************************************************************** !section 12.5(08) !subject Unknown_Discriminant parts on generic formal types. !reference RM95-12.5(8) !reference RM95-3.3(23) !reference RM95-3.7(1) !reference RM95-3.7(8) !reference 95-5307.a rbrukardt@BIX.com 95-9-29 !reference 95-5309.a Gary Dismukes 95-09-30 !from Tucker Taft 95-10-02 !reference as: 95-5310.a Tucker Taft 95-10-2>> !discussion > > 12.5(8) (a note) says that "A discriminant_part is allowed only for certain > > kinds of types, and therefore only for certain kinds of generic formal types. > > See 3.7." > > > > Unfortunately, the rule in 3.7(8) only applies to known_discriminant_parts. > > 3.7 does not contain any rule restricting the usage of > > unknown_discriminant_parts. > > Coincidentally, I came across this definitional gap myself just a few > days ago. There doesn't seem to be a rule disallowing an unknown_ > discriminant_part for arbitrary kinds of formal types. I agree there is a gap. > However... > > > Various syntax rules usually do the job, but for generic formal types, > > the syntax allows unknown_discriminant_parts. Therefore, are the following > > legal? If not, why not? > > > > Generic > > Type Disc (<>) Is (<>); > > Type Flt (<>) Is Digits (<>); > > Type Str (<>) Is New String; > > Procedure .... > > I don't believe an unknown_discriminant_part should be permitted for > these, at least in the first two of the above examples. There is > strong evidence that the intent is that elementary types cannot have > unknown discriminants. That is for sure. I agree the first two should be illegal. There also seems no compelling reason to allow the third either. I believe our intent was to only allow (<>) on formal private types, and on formal derived types where the ancestor type has discriminants, or is tagged (so discriminants could be added). > ... In 3.3(23) we have a definition of indefinite > subtype followed by "otherwise the subtype is a definite subtype > (all elementary subtypes are definite subtypes)." Since types Disc > and Flt are elementary subtypes but also are indefinite subtypes > (since they have unknown discriminants), that's in contradiction to > the parenthetical assertion. There also wouldn't seem to be much > practical use for such types, even if they were allowed. > > In the case of a type such as Str it's somewhat less clear to me whether > this should be disallowed. I don't see any big problem with allowing > it and it might conceivably be of some use (well probably marginal > use if any), but it doesn't seem worth any special rules. Incidentally, > it turns out there's an ACVC test (bc50001) that gives (<>) on a formal > derived access type and a formal derived string type. This test is of > course invalid if either of these uses of unknown_discriminant_part is > deemed illegal. I believe they should be. > So I would suggest there should be a rule that states that an > unknown_discriminant_part is only allowed for (at most) a formal > type that is a composite type. Actually, it seems simpler to me and > more sensible to only allow an unknown_discriminant_part for formal > private types. I'm not sure whether that disallows any useful cases, > but at the moment I can't see any real benefit to allowing (<>) for > the other cases of composite formal types. In fact, since 3.7(1) > discusses unknown_discriminant_parts specifically in the context > of partial views, this suggests that the intent is that they > can only be given for partial views. That's what makes the most > sense to me. As mentioned above, I think we should allow (<>) for formal derived types where the ancestor has discriminants, or is tagged. > Perhaps a restriction against giving (<>) for nonprivate formal types > is somehow a consequence of other rules, but since we're both missing > it, that suggests that at least a clarification is in order. More than a clarification, I am afraid. Definitely a gap. > -- Gary -Tuck **************************************************************** !section 12.5(08) !subject Unknown_Discriminant parts on generic formal types. !reference RM95-12.5(8) !reference RM95-3.3(23) !reference RM95-3.7(1) !reference RM95-3.7(8) !reference 95-5307.a rbrukardt@BIX.com 95-9-29 !reference 95-5309.a Gary Dismukes 95-09-30 !reference 95-5310.a Tucker Taft 95-10-2 !from Bob Duff !reference as: 95-5333.a Robert A Duff 95-10-12>> !discussion > I believe our intent was to only allow (<>) on formal > private types, and on formal derived types where the ancestor > type has discriminants, or is tagged (so discriminants could > be added). This would disallow the following: package Pack is type T(<>) is private; private ... end Pack; generic type Formal(<>) is new Pack.T; -- Legal? package Gen is ... end; type T1 is new Pack.T; package Inst is new Gen(Formal => T1); The above seems pretty harmless to me, so why disallow it? Also, it seems simpler to just echo the rule for known_discrim_parts. That is, "A formal_type_declaration is only permitted to have an unknown_discriminant_part if the formal type is a composite type other than an array type." Or, equivalently, replace unknown_discriminant_part with discriminant_part. - Bob ****************************************************************