Version 1.2 of ai12s/ai12-0116-1.txt

Unformatted version of ai12s/ai12-0116-1.txt version 1.2
Other versions for file ai12s/ai12-0116-1.txt

!standard 3.2.4(15/3)          14-06-19 AI12-0116-1/01
!standard 13.1(9/3)
!standard 13.1(9.1/3)
!class binding interpretation 15-06-19
!status work item 14-06-19
!status received 14-05-26
!priority Low
!difficulty Easy
!qualifier Omission
!subject Private types and predicates
!summary
A subtype predicate aspect can only be specified once per type or subtype.
!question
The following appears to be legal:
package P is type Priv is private with Dynamic_Predicate => Is_OK (Priv); function Is_OK (P : Priv) return Boolean; private function Is_Great (P : Priv) return Boolean; type Priv is private with Dynamic_Predicate => Is_Great (Priv); end P;
Both the private type and the full type are of course type declarations, and there doesn't seem to be anything preventing this. In particular, 13.1.1(14/3) only applies in a single aspect_specification, and these clearly are two different aspect_specifications. We don't have a rule preventing specifying the same aspect twice for the same entity (we do have such a rule for representation aspects and for operational aspects, but predicates are never clearly defined to be either of those kinds of aspects).
Should this be legal? (No.)
!recommendation
(See summary.)
!wording
Add before 3.2.4(15/3): [At the start of the Legality Rules section.]
If a predicate aspect is directly specified for a partial view of a type, that aspect shall not be specified on the corresponding full view of the type.
Modify 13.1(9/3):
If a representation item or aspect_specification is given that directly specifies [an]{a representation} aspect of an entity, then it is illegal to give another representation item or aspect_specification that directly specifies the same aspect of the entity.
Modify 13.1(9.1/3):
If an operational item or aspect_specification is given that directly specifies an {operational} aspect of an entity, then it is illegal to give another operational item or aspect_specification that directly specifies the same aspect of the entity
!discussion
Aspects are one per type, not one per view, so we need to prevent giving one on multiple views. For representation and operation aspects, this is done by the rules in 13.1. But a subtype predicate is neither of those kinds of aspects (neither are preconditions, postconditions, categorization aspects, and others -- it's not the case that we can categorize all aspects this way). We could try to put a blanket rule in 13.1.1 (it has to be there so it clearly can be overrridden for implementation-defined aspects), perhaps as an extension of 13.1.1(14/3), but it's not obvious how to structure that. Thus we just add a rule specifically to 3.2.4.
Type_Invariant is similar; however the definition in 7.3.2(2/3) says that it can be specified on a private_type_definition or on a full_type_definition. That can be read to imply exclusivity. Alternatively, we could add a rule after 7.3.2(6/3): "The Type_Invariant aspect shall not be specified for a full_type_definition if the aspect was specified on the associate partial view." [Editor's note: Should we do this??]
An alternative would be to define both of these as operational aspects. Since 13.1(9.1/3) allow operational aspects on any kind of entity, both could be treated as operational. However, that would drag in some inheritance rules that we probably don't want. In addition, we'd have to have a default value, and support confirming aspects. That might all have worked fine had it been done from the beginning, but now it seems like an invitation for future ARG work to correct introduced bugs.
We don't need an extra rule for Type_Invariant'Class as that is not allowed on full definitions. We don't need an extra rule for any preconditions or postconditions as there already is a rule in 13.1.1 preventing use on bodies. Categorization aspects are required to be given in specifications.
We make a minor correction to 13.1(9/3) and 13.1(9.1/3). When these were reworded to cover aspects as well as other kinds of representation/operational items, the rewording doesn't restrict the kinds of aspects involved. Thus, the rewording can be read to cover all aspects. This makes 13.1(9/3) conflict with 13.1(9.1/3), so we clarify each so that they only cover representation aspects and operational aspects respectively: this just keeps the rules at the meaning that they had in Ada 2005.
!ASIS
No ASIS effect.
!ACATS test
An ACATS B-Test ought to check the new Legality Rule.
!appendix

From: Randy Brukardt
Sent: Monday, May 26, 2014  7:15 PM

Here's a really low priority question that came up when testing the rule that
a predicate can only appear on a type_declaration or subtype_declaration.

The following appears to be legal:

    package P is
       type Priv is private
          with Dynamic_Predicate => Is_OK (Priv);
       function Is_OK (P : Priv) return Boolean;
    private
       function Is_Great (P : Priv) return Boolean;
       type Priv is private
          with Dynamic_Predicate => Is_Great (Priv);
    end P;

Both the private type and the full type are of course type declarations, and
there doesn't seem to be anything preventing this. In particular,
13.1.1(14/3) only applies in a single aspect_specification, and these clearly
are two different aspect_specifications. We *don't* have a rule preventing
specifying the same aspect twice for the same entity (we do have such a rule
for representation aspects and for operational aspects, but predicates are
never clearly defined to be either of those kinds of aspects).

Thus, we have two predicates of the same kind directly specified for the same
subtype. I'm not sure that we planned on that, although it appears that the
Dynamic Semantics wording in particular does work in this case. (We had allowed
for the case where both a Dynamic_Predicate and a Static_Predicate were
specified on the same type.)

This seems likely to have been a mistake, but whether it is bad enough that
we ought to actually reject it isn't clear. OTOH, having more than one
expression directly applying as a static or dynamic predicate is clearly
more implementation work (must use list rather than a single component). But
the work isn't likely to be that big of a deal (other than for implementers
 who didn't know about it and end up doing that part of their compiler twice).

So:
(1) Should this be legal?
(2) If not, should predicates clearly be defined as operational aspects so
    that 13.1(9.1/3) applies?
(3) Or should we just add a legality rule for this case (possibly after
    3.2.4(23/3))?

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

From: Tucker Taft
Sent: Tuesday, May 27, 2014  9:22 AM

> (1) Should this be legal?

No.

> (2) If not, should predicates clearly be defined as operational 
> aspects so that 13.1(9.1/3) applies?

These are subtype aspects, not type aspects, but I guess we could have the
same representational vs. operational split.

> (3) Or should we just add a legality rule for this case (possibly 
> after 3.2.4(23/3))?

Perhaps we could say that all type and subtype aspects are either
representational or operational, with the default being operational for
subtype, and representational for types, unless otherwise specified.

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

From: Randy Brukardt
Sent: Tuesday, May 27, 2014  7:15 PM

> > (2) If not, should predicates clearly be defined as operational 
> > aspects so that 13.1(9.1/3) applies?
> 
> These are subtype aspects, not type aspects, but I guess we could have 
> the same representational vs. operational split.

Good point.
 
> > (3) Or should we just add a legality rule for this case (possibly 
> > after 3.2.4(23/3))?
> 
> Perhaps we could say that all type and subtype aspects are either 
> representational or operational, with the default being operational 
> for subtype, and representational for types, unless otherwise 
> specified.

I'd say it's not worth it, at least in this case. We already have all of the
rules about inheritance and the like defined here. Probably we just need a
special rule, just like we have for incomplete subtypes. (Since we don't allow
predicates on incomplete types, the only way to have multiples is to have a
 private type and its full type.) Something like:

If a predicate aspect is directly specified for a partial view of a type, that
aspect shall not be specified on the corresponding full view of the type.

[I used "partial view of a type" so it encompasses both private types and
private extensions.]

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

From: Steve Baird
Sent: Tuesday, May 27, 2014  2:10 PM

> The following appears to be legal:
>
>      package P is
>         type Priv is private
>            with Dynamic_Predicate => Is_OK (Priv);
>         function Is_OK (P : Priv) return Boolean;
>      private
>         function Is_Great (P : Priv) return Boolean;
>         type Priv is private
>            with Dynamic_Predicate => Is_Great (Priv);
>      end P;

Doesn't this example violate 13.1(9/3):
   If a representation item or aspect_specification is given that
   directly specifies an aspect of an entity, then it is illegal to give
   another representation item or aspect_specification that directly
   specifies the same aspect of the entity.
?

Note that this complements 13.1.1(14/3); the two rules cover different cases.

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

From: Steve Baird
Sent: Tuesday, May 27, 2014  2:24 PM

Never mind. I missed the point that this example has no representation items.

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

From: Randy Brukardt
Sent: Tuesday, May 27, 2014  2:43 PM

13.1(9/3) only applies to representation aspects, and a predicate is not a
representation aspect. (Representation items can only specify a representation
aspects.)

13.1(9.1/3) is similar, but it only applies to operational aspects, but again a
predicate is not an operational aspect, either.

Jeff's wording changes to those paragraphs are arguably incorrect, because one
could argue that the wording applies to all aspects specified by an
aspect_clause (which we *definitely* don't want - those rules are in 13.1.1 if
we want them). Moreover, it wouldn't make much sense to put such a rule for
other kinds of aspect into 13.1(9/3) which is mainly talking about
representation items (and thus representation aspects). Finally, 13.1(9/3) was
only about representation aspects in Ada 2005 and we had no intent of changing
it to cover anything else.

"If a representation item or aspect_specification is given that directly
specifies [an]{a representation} aspect of an entity, then it is illegal to
give another representation item or aspect_specification that directly
specifies the same aspect of the entity."

And similarly for 13.1(9.1/3).

I'd consider this a presentation change (since it clearly follows from the
intent as noted above), but I might get some debate on that.

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


Questions? Ask the ACAA Technical Agent