Version 1.1 of ais/ai-00098.txt

Unformatted version of ais/ai-00098.txt version 1.1
Other versions for file ais/ai-00098.txt

!standard 12.05 (08)          97-11-14 AI95-00098/01
!class binding interpretation 95-10-12
!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
!subject unknown_discriminant_parts on generic formal types.
!summary 97-05-08
A generic formal type must not have an unknown_discriminant_part, unless the type is a composite non-array type.
!question 97-05-08
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? (No.)
generic type Disc (<>) is (<>); -- Illegal! type Flt (<>) is digits (<>); -- Illegal! type Str (<>) is new String; -- Illegal! procedure ....
!recommendation 97-05-08
(See Summary.)
!wording 97-05-08
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 97-05-08
The intent is that elementary and array types cannot have discriminant parts (known or unknown).
!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
<<reference as: 95-5307.a rbrukardt@BIX.com 95-9-29>>
!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

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

Questions? Ask the ACAA Technical Agent