!standard 13.1(9/3) 14-10-02 AI12-0116-1/03 !standard 13.1(9.1/3) !class binding interpretation 15-06-19 !status Corrigendum 2015 14-07-11 !status ARG Approved 6-0-1 13-06-29 !status work item 14-06-19 !status received 14-05-26 !priority Low !difficulty Easy !qualifier Omission !subject Private types and predicates !summary An aspect cannot be specified on two views of the same entity. !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 null record 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 Modify 13.1(9/3): A representation item that directly specifies an aspect of a subtype or type shall appear after the type is completely defined (see 3.11.1), and before the subtype or type is frozen (see 13.14). [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.] Modify 13.1(9.1/3): An operational item that directly specifies an aspect of an entity shall appear before the entity is frozen (see 13.14). [If an operational item or aspect_specification is given that directly specifies an 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.] Add after 13.1(9.1/3): If a representation item, operational item, or aspect_specification is given that directly specifies an aspect of an entity, then it is illegal to give another representation item, operational item, or aspect_specification that directly specifies the same aspect of the entity. Add an AARM note after 13.1.1(14/3): Ramification: This rule prevents multiple specifications in the same aspect_specification. Rules in 13.1 prevent multiple specifications in different aspect_specifications (on different views of the same type, for instance) or between operational or representation items and an aspect_specification, even for aspects that are neither operational nor representation aspects. !discussion Aspects are one per type, not one per view, so we need to prevent giving one on multiple views. For representation and operational 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). The existing rules in 13.1(9/3) and 13.1(9.1/3) could be read to cover all aspects. That was purely unintentional; when these paragraphs were reworded to cover aspects as well as other kinds of representation/operational items, the rewording didn'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) - they both seem to apply in some cases. We have decided to extend the rules in 13.1 to cover all aspects. The best way to do this was to drop the existing specific rules and rather create a more general rule that clearly applies to all kinds of items and specifications. Arguably, such a rule belongs in 13.1.1 (as it is a rule applying to all aspect_specifications), but it also belongs in 13.1 (as it affects all of representation items, operational items, and aspect_specifications). Since it is already in 13.1, we have left it there, but added an AARM note to 13.1.1 so that language laywers will know that it exists. An alternative would be to define both subtype predicates and type invariants as operational aspects. Since 13.1(9.1/3) allows 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 wouldn't have needed any additional rules for Type_Invariant'Class as that is not allowed on full definitions. We wouldn't have needed rules for any preconditions or postconditions as there already is a rule in 13.1.1 preventing use on bodies. Similarly, categorization aspects are required to be given in specifications. But the new rule is harmless in all of these cases. !corrigendum 13.1(9/3) @drepl A representation item that directly specifies an aspect of a subtype or type shall appear after the type is completely defined (see 3.11.1), and before the subtype or type is frozen (see 13.14). If a representation item or @fa is given that directly specifies an aspect of an entity, then it is illegal to give another representation item or @fa that directly specifies the same aspect of the entity. @dby A representation item that directly specifies an aspect of a subtype or type shall appear after the type is completely defined (see 3.11.1), and before the subtype or type is frozen (see 13.14). !corrigendum 13.1(9.1/3) @drepl An operational item that directly specifies an aspect of an entity shall appear before the entity is frozen (see 13.14). If an operational item or @fa is given that directly specifies an aspect of an entity, then it is illegal to give another operational item or @fa that directly specifies the same aspect of the entity. @dby An operational item that directly specifies an aspect of an entity shall appear before the entity is frozen (see 13.14). If a representation item, operational item, or @fa is given that directly specifies an aspect of an entity, then it is illegal to give another representation item, operational item, or @fa that directly specifies the same aspect of the entity. !ASIS No ASIS effect. !ACATS test An ACATS B-Test ought to check the example in the !question. !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. ***************************************************************