!standard 3.2.1(3) 10-11-18 AI05-0183-1/07 !standard 3.2.2(2) !standard 3.3.1(2/2) !standard 3.8(6) !standard 3.9.3(1.1/2) !standard 6.1(2/2) !standard 6.7(2/2) !standard 9.5.2(2/2) !standard 7.1(3) !standard 7.3(2) !standard 7.3(3) !standard 9.1(2/2) !standard 9.1(3/2) !standard 9.4(2/2) !standard 9.4(3/2) !standard 9.5.2(2/2) !standard 11.1(2) !standard 12.1(3) !standard 12.3(2/2) !standard 12.4(2/2) !standard 12.5(2) !standard 12.6(2.1/2) !standard 12.6(2.2/2) !standard 12.7(2) !standard 13.1(0.1/2) !standard 13.3(5/1) !standard 13.3.1(0) !standard 13.14(7.1/2) !class amendment 09-11-01 !status Amendment 2012 10-09-01 !status work item 10-11-19 !status ARG Approved 8-0-2 10-10-29 !status work item 09-11-01 !status received 09-11-01 !priority Medium !difficulty Medium !subject Aspect Specifications !summary To support the specification of pre- and postconditions, as well as invariants on types and object, we propose a general notation for specifying "aspects" of an entity as part of its declaration, rather than with a separate aspect clause. !problem There is a desire to be able to specify "aspects" of subprograms such as pre- and postconditions. Unfortunately, specifying aspects for subprograms using a pragma or an attribute_definition_clause is generally awkward in Ada, because subprograms can be overloaded. Having to insert a local renaming simply to provide a unique name is verbose, and at least in some cases, the aspect to be specified belongs in close proximity with the declaration. More generally, specifying attributes or other aspects of an entity with a separate clause or pragma is not always desirable, as the aspect may be integral to the appropriate use of the entity. !proposal We propose to allow certain aspects of an entity to be specified as part of the declaration of the entity, using an aspect_specification that is placed immediately in front of the semicolon ending the declaration: aspect_specification ::= WITH aspect_mark [=> expression] {, aspect_mark [=> expression] } The aspect_specification is an optional element in the following kinds of declarations: * object_declaration; * full_type_declaration; * subtype_declaration; * component_declaration; * subprogram_declaration; * abstract_subprogram_declaration; * null_procedure_declaration; * package_declaration; * private_type_declaration; * private_extension_declaration; * task_type_declaration; * single_task_declaration; * protected_type_declaration; * single_protected_declaration; * entry_declaration; * exception_declaration; * generic_declaration; * generic_instantiation; * generic_formal_parameter_declaration. Aspect specification are not permitted on renaming declarations, as that would seem to break the underlying model of renaming (that properties are the same as the renamed entity). At most one occurrence of each aspect is allowed within a single aspect_specification. The named aspect must be an aspect that can be specified for the given kind of entity. The names in the expressions of an aspect_specification are resolved *not* at the point of the associated declaration, but rather at the freezing point of the associated entity. If the aspect_specification occurs within a visible part, declarations occuring after the freezing point or within the corresponding private part are not considered. The expression may be omitted only when the aspect is of a boolean type, in which case it is equivalent to being specified as True. !wording Replace 3.2.1(3) by: full_type_declaration ::= TYPE defining_identifier [known_discriminant_part] IS type_definition [aspect_specification]; | task_type_declaration | protected_type_declaration Replace 3.2.2(2) by: subtype_declaration ::= SUBTYPE defining_identifier IS subtype_indication [aspect_specification]; Replace 3.3.1(2/2) by: object_declaration ::= defining_identifier_list : [ALIASED] [CONSTANT] subtype_indication [:= expression] [aspect_specification]; | defining_identifier_list : [ALIASED] [CONSTANT] access_definition [:= expression] [aspect_specification]; | defining_identifier_list : [ALIASED] [CONSTANT] array_type_definition [:= expression] [aspect_specification]; | single_task_declaration | single_protected_declaration Replace 3.8(6) by: component_declaration ::= defining_identifier_list : component_definition [:= default_expression] [aspect_specification]; Replace 3.9.3(1.1/2) by: abstract_subprogram_declaration ::= [overriding_indicator] subprogram_specification IS ABSTRACT [aspect_specification]; Replace 6.1(2/2) by: subprogram_declaration ::= [overriding_indicator] subprogram_specification [aspect_specification]; Replace 6.7(2/2) by: null_procedure_declaration ::= [overriding_indicator] procedure_specification IS NULL [aspect_specification]; Replace 7.1(3) by: package_specification ::= PACKAGE defining_program_unit_name [aspect_specification] IS {basic_declarative_item} [PRIVATE {basic_declarative_item}] END [[parent_unit_name.]identifier] Replace 7.3(2) by: private_type_declaration ::= TYPE defining_identifier [discriminant_part] IS [[ABSTRACT] TAGGED] [LIMITED] PRIVATE [aspect_specification]; Replace 7.3(3/2) by: private_extension_declaration ::= TYPE defining_identifier [discriminant_part] IS [ABSTRACT] [LIMITED | SYNCHRONIZED] NEW ancestor_subtype_indication [AND interface_list] WITH PRIVATE [aspect_specification]; Replace 9.1(2/2) by: task_type_declaration ::= TASK TYPE defining_identifier [known_discriminant_part] [aspect_specification] [IS [NEW interface_list WITH] task_definition]; Replace 9.1(3/2) by: single_task_declaration ::= TASK defining_identifier [aspect_specification] [IS [NEW interface_list WITH] task_definition]; Replace 9.4(2/2) by: protected_type_declaration ::= PROTECTED TYPE defining_identifier [known_discriminant_part] [aspect_specification] IS [NEW interface_list WITH] protected_definition; Replace 9.4(3/2) by: single_protected_declaration ::= PROTECTED defining_identifier [aspect_specification] IS [NEW interface_list WITH] protected_definition; Replace 9.5.2(2/2) by: entry_declaration ::= [overriding_indicator] ENTRY defining_identifier [(discrete_subtype_definition)] parameter_profile [aspect_specification]; Replace 11.1(2) by: exception_declaration ::= defining_identifier_list : exception [aspect_specification]; Replace 12.1(3) by: generic_subprogram_declaration ::= generic_formal_part subprogram_specification [aspect_specification]; [AARM NOTE: a generic package can have an aspect_specification because a package_specification allows an aspect_specification.] Replace 12.3(2/2) by: generic_instantiation ::= package defining_program_unit_name is new generic_package_name [generic_actual_part] [aspect_specification]; | [overriding_indicator] procedure defining_program_unit_name is new generic_procedure_name [generic_actual_part] [aspect_specification]; | [overriding_indicator] function defining_designator is new generic_function_name [generic_actual_part] [aspect_specification]; Replace 12.4(2/2) by: formal_object_declaration ::= defining_identifier_list : mode [null_exclusion] subtype_mark [:= default_expression] [aspect_specification]; | defining_identifier_list : mode access_definition [:= default_expression] [aspect_specification]; Replace 12.5(2) by: formal_type_declaration ::= TYPE defining_identifier[discriminant_part] IS formal_type_definition [aspect_specification]; Replace 12.6(2.1/2-2.2/2) by: formal_concrete_subprogram_declaration ::= WITH subprogram_specification [IS subprogram_default] [aspect_specification]; formal_abstract_subprogram_declaration ::= WITH subprogram_specification IS ABSTRACT [subprogram_default] [aspect_specification]; Replace 12.7(2) by: formal_package_declaration ::= WITH package defining_identifier IS NEW generic_package_name formal_package_actual_part [aspect_specification]; Add the following at the end of 13.1(0.1/1): In addition to representation and operational items, aspects of entities may be specified using an aspect_specification (see 13.3.1), which is an optional element of certain kinds of declarations. Modify 13.1(9, 9.1/1) as follows: 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. An operational item that directly specifies an aspect of a type shall appear before the type is frozen (see 13.14). If an operational item {or aspect_specification} is given that directly specifies an aspect of a type, then it is illegal to give another operational item {or aspect_specification} that directly specifies the same aspect of the type. Revise 13.3(5/1) as follows: ... Each specifiable attribute constitutes an operational aspect or aspect of representation{; the name of the aspect is that of the attribute}. Add the following section: 13.3.1 Aspect Specifications [Redundant: Certain representation or operational aspects of an entity may be specified as part of its declaration using an aspect_specification, rather than using a separate representation or operational item.] The declaration with the aspect_specification is termed the *associated declaration*. Syntax aspect_specification ::= WITH aspect_mark [=> aspect_definition] {, aspect_mark [=> aspect_definition] } aspect_mark ::= aspect_identifier['Class] aspect_definition ::= name | expression AARM NOTE: The aspect_specification is an optional element in most kinds of declarations. Here is a list of all kinds of declarations and an indication of whether or not they allow aspect clauses, and in some cases a short discussion of why (* = allowed, NO = not allowed) basic_declaration type_declaration full_type_declaration* ... task_type_declaration* protected_type_declaration* incomplete_type_declaration -- NO private_type_declaration* private_extension_declaration* subtype_declaration* object_declaration* ... single_task_declaration* single_protected_declaration* number_declaration -- NO subprogram_declaration* abstract_subprogram_declaration* null_procedure_declaration* package_declaration* renaming_declaration -- NO -- Allowing a renaming to change operational or representational -- aspects would seem to break the underlying model of renaming. exception_declaration* generic_declaration* generic_instantiation* enumeration_literal_specification -- NO discriminant_specification -- NO component_declaration* loop_parameter_specification -- NO parameter_specification -- NO subprogram_body -- NO entry_declaration* entry_index_specification -- NO choice_parameter_specification -- NO generic_formal_parameter_declaration* -- There are no language-defined aspects that -- may be specified on generic formals, but implementations -- might support some. The implementation would have to -- define the matching rule. extended_return_statement -- NO End of AARM Note. Name Resolution An aspect_mark identifies an aspect of the entity defined by the associated declaration (the *associated entity*); the aspect denotes an object, a value, an expression, a subprogram, or some other kind of entity. If the aspect_mark identifies: * an aspect that denotes an object, the aspect_definition shall be a name; the expected type for the name is the type of the identified aspect of the associated entity; * an aspect that is a value or an expression, the aspect_definition shall be an expression; the expected type for the expression is the type of the identified aspect of the associated entity; * an aspect that denotes a subprogram, the aspect_definition shall be a name; the expected profile for the name is the profile required for the aspect of the associated entity; * an aspect that denotes some other kind of entity, the aspect_definition shall be a name, and the name shall resolve to denote an entity of the appropriate kind. The usage names in an aspect_definition [Redundant: are not resolved at the point of the associated declaration, but rather] are resolved at the end of the immediately enclosing declaration list, or at the first freezing point of the associated entity, whichever comes first. If the associated declaration is for a subprogram or entry, the names of the formal parameters are directly visible within the aspect_definition, as are certain attributes, as specified elsewhere in this International Standard for the identified aspect. If the associated declaration is a type_declaration, within the aspect_definition the names of any visible components, protected subprograms, and entries are directly visible, and the name of the first subtype denotes the current instance of the type (see 8.6). If the associated declaration is a subtype_declaration, within the aspect_definition the name of the new subtype denotes the current instance of the (sub)type. Legality Rules If the freezing point of the associated entity comes before the end of the immediately enclosing declaration list, then each usage name in the aspect_definition shall resolve to the same declaration at both places. At most one occurrence of each aspect_mark is allowed within a single aspect_specification. The aspect identified by the aspect_mark shall be an aspect that can be specified for the associated entity. The aspect_definition associated with a given aspect_mark may be omitted only when the aspect_mark identifies an aspect of a boolean type, in which case it is equivalent to the aspect_definition being specified as True. If the aspect_mark includes 'Class, then the associated entity shall be a tagged type or the primitive subprogram of a tagged type. Static Semantics Depending on which aspect is identified by the aspect_mark, an aspect_definition specifies a name that denotes a subprogram, object, or other kind of entity, or an expression, which is either evaluated to produce a single value, or which (as in a precondition) is to be evaluated at particular points during later execution. The identified aspect of the associated entity is as specified by the aspect_definition (or by the default of True when boolean). If the aspect_mark includes 'Class, then: * if the associated entity is a tagged type, the specification applies to all descendants of the type; * if the associated entity is a primitive subprogram of a tagged type T, the specification applies to the corresponding primitive subprogram of all descendants of T. All specifiable operational and representation attributes may be specified with an aspect_specification instead of an attribute_definition_clause (see 13.3). The attribute_designator is used for the aspect_mark. In addition, other operational and representation aspects not associated with specifiable attributes may be specified, as specified elsewhere in this International Standard. In the case of aspects specifiable with pragmas, the pragma identifier is used for the aspect_mark. Alternative legality and semantics rules may apply for particular aspects, as specified elsewhere in this International Standard. Dynamic Semantics At the freezing point of the associated entity, the aspect_specification is elaborated. The elaboration of the aspect_specification includes the evaluation of the name or expression, unless the aspect itself is an expression. If the corresponding aspect represents an expression (as in a precondition), the elaboration has no effect; the expression is evaluated later at points within the execution as specified elsewhere in this International Standard for the particular aspect. Add after 13.14(7.1/2): * At the freezing point of the entity associated with an aspect_specification, any expressions or names within the aspect_specification cause freezing. !discussion This syntax was invented to allow pre- and postconditions to be specified for subprograms without worrying about overloading, and without resorting to pragmas. The syntax allows additional aspect names to be added without introducing additional reserved words. Various uses are imagined over and above pre- and postconditions. Here are a number of examples: function Pop(S : in out Stack) return Elem with Pre => not Is_Empty(S), Post => not Is_Full(S); type Atomic_Array is array(Positive range <>) of Natural with Atomic_Components; type Set is interface with Invariant'Class => (Is_Empty(X)) = (Count(X) = 0); function Union(X, Y : Set) return Set is abstract with Post'Class => Count(Union'Result) = Count(X) + Count(Y); type R is record X : Positive := 0 with Independent => True; Y : Natural := 77 with Atomic => True; end record; type Shared_Bit_Vector is array(0..15) of Boolean with Packing, Independent_Components; type Bit_Vector is array(0..15) of Boolean with Component_Size => 1; This presumes that aspect identifiers generally match attribute names or pragma names. We considered, in the case of pragmas, choosing nouns rather than adjectives for aspect names, so the names might work better after the preposition "with". Hence, we considered "Atomicity" or "Independence" rather than "Atomic" and "Independent." However, that seemed to be introducing unnecessary complexity, and adding "=> True" makes the adjectives work grammatically, so by default the aspect name will be presumed to be the same as the pragma. Pragma Pack currently specifies that its aspect is "packing," but we might want to change that for consistency. See AI05-0112-1. We use "'Class" as an indication that the aspect specification applies to all descendants of the type, or for a subprogram, the corresponding primitive subprogram for all descendants of the type. Other alternatives would be names such as "Inherited_Pre", but Pre'Class meaning it applies to T'Class seems more natural. We defer resolving the names in the aspect_definition to the first freezing point or end of the declaration list because in many cases the entities referenced in the aspect_definition will necessarily, or more conveniently, be declared after the entity with the aspect specification. For example, for a type, any aspect that refers to an operation of the type will be a forward reference. For a subprogram, an aspect that refers to another subprogram will often be a forward reference, as ordering the subprograms based on the aspect_definitions would be painful and sometimes impossible. If the freezing point comes before the end of the enclosing declaration list, we require the usage names in the aspect_definition to resolve to the same entities at the two places. Because there is no explicit indication of where a freezing point occurs in the source, we felt it would be too confusing if we didn't require this. This means that if a freezing point "moves" and thereby crosses over, for example, the overriding of an inherited subprogram (of a non-tagged type), the compiler would complain rather than silently reinterpreting the name in the aspect_definition. For example: type New_T is new T with Type_Invariant => Is_Valid(New_T); Default_Obj : New_T; -- Here we freeze New_T function Is_Valid(Y : New_T) return Boolean; -- Here we override Is_Valid private -- Here we reach the end of the declaration list. In a case like this, the user almost certainly wants to refer to the overriding of Is_Valid, but since the freezing happens before the overriding, without the rule to require that the names in the aspect_definition resolve to the same thing, they would not get what they expected. With this rule, the compiler would complain, and the user would (hopefully ;-) realize they need to move the declaration of Default_Obj down a little further so Is_Valid can be overridden first. We don't bother talking about the case of a declaration with multiple defining_identifiers in its defining_identifier_list, because RM 3.3.1(7) already says such a multi-defining-identifier declaration is equivalent to a sequence of single-defining-identifier declarations. Much of the semantics is left to the particular aspects, as it is hard to talk about such things in a general way. !corrigendum 3.2.1(3) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier [known_discriminant_part] >@b<@ft>@fa< type_definition; | task_type_declaration | protected_type_declaration>> @dby @xcode<@fa@b<@ft>@fa< defining_identifier [known_discriminant_part] >@b<@ft>@fa< type_definition [aspect_specification]; | task_type_declaration | protected_type_declaration>> !corrigendum 3.2.2(2) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier >@b<@ft>@fa< subtype_indication;>> @dby @xcode<@fa@b<@ft>@fa< defining_identifier >@b<@ft>@fa< subtype_indication [aspect_specification];>> !corrigendum 3.3.1(2/2) @drepl @xcode<@fa@b<@ft>@fa<] [>@b<@ft>@fa<] subtype_indication [:= expression]; | defining_identifier_list : [>@b<@ft>@fa<] [>@b<@ft>@fa<] access_definition [:= expression]; | defining_identifier_list : [>@b<@ft>@fa<] [>@b<@ft>@fa<] array_type_definition [:= expression]; | single_task_declaration | single_protected_declaration>> @dby @xcode<@fa@b<@ft>@fa<] [>@b<@ft>@fa<] subtype_indication [:= expression] [aspect_specification]; | defining_identifier_list : [>@b<@ft>@fa<] [>@b<@ft>@fa<] access_definition [:= expression] [aspect_specification]; | defining_identifier_list : [>@b<@ft>@fa<] [>@b<@ft>@fa<] array_type_definition [:= expression] [aspect_specification]; | single_task_declaration | single_protected_declaration>> !corrigendum 3.8(6) @drepl @xcode<@fa> @dby @xcode<@fa> !corrigendum 3.9.3(1.1/2) @drepl @xcode<@fa@b<@ft>@fa<;>> @dby @xcode<@fa@b<@ft>@fa< [aspect_specification];>> !corrigendum 6.1(2/2) @drepl @xcode<@fa> @dby @xcode<@fa> !corrigendum 6.7(2/2) @drepl @xcode<@fa@b<@ft>@fa<;>> @dby @xcode<@fa@b<@ft>@fa< [aspect_specification];>> !corrigendum 7.1(3) @drepl @xcode<@fa@b<@ft>@fa< defining_program_unit_name >@b<@ft>@fa< {basic_declarative_item} [>@b<@ft>@fa< {basic_declarative_item}] >@b<@ft>@fa< [[parent_unit_name.]identifier]>> @dby @xcode<@fa@b<@ft>@fa< defining_program_unit_name [aspect_specification] >@b<@ft>@fa< {basic_declarative_item} [>@b<@ft>@fa< {basic_declarative_item}] >@b<@ft>@fa< [[parent_unit_name.]identifier]>> !corrigendum 7.3(2) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier [discriminant_part] >@b<@ft>@fa< [[>@b<@ft>@fa<] >@b<@ft>@fa<] [>@b<@ft>@fa<] >@b<@ft>@fa<;>> @dby @xcode<@fa@b<@ft>@fa< defining_identifier [discriminant_part] >@b<@ft>@fa< [[>@b<@ft>@fa<] >@b<@ft>@fa<] [>@b<@ft>@fa<] >@b<@ft>@fa< [aspect_specification];>> !corrigendum 7.3(3/2) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier [discriminant_part] >@b<@ft>@fa< [>@b<@ft>@fa<] [>@b<@ft>@fa< | >@b<@ft>@fa<] >@b<@ft>@fa< ancestor_subtype_indication [>@b<@ft>@fa< interface_list] >@b<@ft>@fa<;>> @dby @xcode<@fa@b<@ft>@fa< defining_identifier [discriminant_part] >@b<@ft>@fa< [>@b<@ft>@fa<] [>@b<@ft>@fa< | >@b<@ft>@fa<] >@b<@ft>@fa< ancestor_subtype_indication [>@b<@ft>@fa< interface_list] >@b<@ft>@fa< [aspect_specification];>> !corrigendum 9.1(2/2) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier [known_discriminant_part] [>@b<@ft>@fa< [>@b<@ft>@fa< interface_list >@b<@ft>@fa<] task_definition];>> @dby @xcode<@fa@b<@ft>@fa< defining_identifier [known_discriminant_part] [aspect_specification] [>@b<@ft>@fa< [>@b<@ft>@fa< interface_list >@b<@ft>@fa<] task_definition];>> !corrigendum 9.1(3/2) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier [>@b<@ft>@fa< [>@b<@ft>@fa< interface_list >@b<@ft>@fa<] task_definition];>> @dby @xcode<@fa@b<@ft>@fa< defining_identifier [aspect_specification] [>@b<@ft>@fa< [>@b<@ft>@fa< interface_list >@b<@ft>@fa<] task_definition];>> !corrigendum 9.4(2/2) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier [known_discriminant_part] >@b<@ft>@fa< [>@b<@ft>@fa< interface_list >@b<@ft>@fa<] protected_definition;>> @dby @xcode<@fa@b<@ft>@fa< defining_identifier [known_discriminant_part] [aspect_specification] >@b<@ft>@fa< [>@b<@ft>@fa< interface_list >@b<@ft>@fa<] protected_definition;>> !corrigendum 9.4(3/2) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier >@b<@ft>@fa< [>@b<@ft>@fa< interface_list >@b<@ft>@fa<] protected_definition;>> @dby @xcode<@fa@b<@ft>@fa< defining_identifier [aspect_specification] >@b<@ft>@fa< [>@b<@ft>@fa< interface_list >@b<@ft>@fa<] protected_definition;>> !corrigendum 9.5.2(2/2) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier [(discrete_subtype_definition)] parameter_profile;>> @dby @xcode<@fa@b<@ft>@fa< defining_identifier [(discrete_subtype_definition)] parameter_profile [aspect_specification];>> !corrigendum 11.1(2) @drepl @xcode<@fa@b<@ft>@fa<;>> @dby @xcode<@fa@b<@ft>@fa< [aspect_specification];>> !corrigendum 12.1(3) @drepl @xcode<@fa> @dby @xcode<@fa> !corrigendum 12.3(2/2) @drepl @xcode<@fa@b<@ft>@fa< defining_program_unit_name >@b<@ft>@fa< >@b<@ft>@fa< generic_package_name [generic_actual_part]; | [overriding_indicator] >@b<@ft>@fa< defining_program_unit_name >@b<@ft>@fa< >@b<@ft>@fa< generic_procedure_name [generic_actual_part]; | [overriding_indicator] >@b<@ft>@fa< defining_designator >@b<@ft>@fa< >@b<@ft>@fa< generic_function_name [generic_actual_part];>> @dby @xcode<@fa@b<@ft>@fa< defining_program_unit_name >@b<@ft>@fa< >@b<@ft>@fa< generic_package_name [generic_actual_part] [aspect_specification]; | [overriding_indicator] >@b<@ft>@fa< defining_program_unit_name >@b<@ft>@fa< >@b<@ft>@fa< generic_procedure_name [generic_actual_part] [aspect_specification]; | [overriding_indicator] >@b<@ft>@fa< defining_designator >@b<@ft>@fa< >@b<@ft>@fa< generic_function_name [generic_actual_part] [aspect_specification];>> !corrigendum 12.4(2/2) @drepl @xcode<@fa> @dby @xcode<@fa> !corrigendum 12.5(2) @drepl @xcode<@fa@b<@ft>@fa< defining_identifier[discriminant_part] >@b<@ft>@fa< formal_type_definition;>> @dby @xcode<@fa@b<@ft>@fa< defining_identifier[discriminant_part] >@b<@ft>@fa< formal_type_definition [aspect_specification];>> !corrigendum 12.6(2.1/2) @drepl @xcode<@fa@b<@ft>@fa< subprogram_specification [>@b<@ft>@fa< subprogram_default];>> @dby @xcode<@fa@b<@ft>@fa< subprogram_specification [>@b<@ft>@fa< subprogram_default] [aspect_specification];>> !corrigendum 12.6(2.2/2) @drepl @xcode<@fa@b<@ft> @fa@b<@ft>@fa< [subprogram_default];>> @dby @xcode<@fa@b<@ft> @fa@b<@ft>@fa< [subprogram_default] [aspect_specification];>> !corrigendum 12.7(2) @drepl @xcode<@fa@b<@ft> @fa@b<@ft>@fa< generic_package_name formal_package_actual_part;>> @dby @xcode<@fa@b<@ft> @fa@b<@ft>@fa< generic_package_name formal_package_actual_part [aspect_specification];>> !corrigendum 13.1(0.1/1) @drepl Representation and operational items can be used to specify aspects of entities. Two kinds of aspects of entities can be specified: aspects of representation and operational aspects. Representation items specify how the types and other entities of the language are to be mapped onto the underlying machine. Operational items specify other properties of entities. @dby Representation and operational items can be used to specify aspects of entities. Two kinds of aspects of entities can be specified: aspects of representation and operational aspects. Representation items specify how the types and other entities of the language are to be mapped onto the underlying machine. Operational items specify other properties of entities. In addition to representation and operational items, aspects of entities may be specified using an @fa 13.3.1), which is an optional element of certain kinds of declarations. !corrigendum 13.3(5/1) @drepl An @fa is allowed in an @fa only if this International Standard explicitly allows it, or for an implementation-defined attribute if the implementation allows it. Each specifiable attribute constitutes an operational aspect or an aspect of representation. @dby An @fa is allowed in an @fa only if this International Standard explicitly allows it, or for an implementation-defined attribute if the implementation allows it. Each specifiable attribute constitutes an operational aspect or an aspect of representation; the name of the aspect is that of the attribute. !corrigendum 13.3.1(0) @dinsc Certain representation or operational aspects of an entity may be specified as part of its declaration using an @fa, rather than using a separate representation or operational item. The declaration with the @fa is termed the @i. @i<@s8> @xcode<@fa@b<@ft>@fa< aspect_mark [=@> aspect_definition] {, aspect_mark [=@> aspect_definition] }>> @xcode<@fa@i<@ft>@fa@ft@fa<]>> @xcode<@fa> @i<@s8> An @fa identifies an aspect of the entity defined by the associated declaration (the @i); the aspect denotes an object, a value, an expression, a subprogram, or some other kind of entity. If the @fa identifies: @xbullet shall be a @fa. The expected type for the @fa is the type of the identified aspect of the associated entity.> @xbullet shall be an @fa. The expected type for the @fa is the type of the identified aspect of the associated entity.> @xbullet shall be a @fa; the expected profile for the @fa is the profile required for the aspect of the associated entity.> @xbullet shall be a @fa, and the @fa shall resolve to denote an entity of the appropriate kind.> The usage names in an @fa are not resolved at the point of the associated declaration, but rather are resolved at the end of the immediately enclosing declaration list, or at the first freezing point of the associated entity, whichever comes first. If the associated declaration is for a subprogram or entry, the names of the formal parameters are visible within the @fa, as are certain attributes, as specified elsewhere in this International Standard for the identified aspect. If the associated declaration is a @fa, within the @fa the names of any components are visible, and the name of the first subtype denotes the current instance of the type (see 8.6). If the associated declaration is a @fa, within the @fa the name of the new subtype denotes the current instance of the (sub)type. @i<@b> !example (See discussion.) !ACATS test ACATS B-Tests should be generated for the legality rules here. ACATS C-Tests will be generated for specific aspects; there isn't a need to see if the clauses are supported individually. !ASIS [From Tucker.] !appendix From: Yannick Moy Sent: Tuesday, April 20, 2010 8:58 AM I would like to question the following legality rule for user-defined kinds of aspect_mark: "At most one occurrence of each aspect_mark is allowed within a single aspect_specification." Indeed, it could be useful to have multiple user aspects of the same kind. This is the case, e.g., for an aspect we could add to GNAT, which would give the ability to specify unit tests, as in: function Sqrt (X : Integer) return Integer with Test => if X > 100 then Sqrt'Result >= 10, Test => if X < 100 then Sqrt'Result < 10, Test => if X = 100 then Sqrt'Result = 10, Test => Sqrt'Result >= 0; Notice that this aspect is essentially a special kind of postcondition. The goal in having a special aspect for it and allowing multiple occurrences of this aspect on the same subprogram is to allow compilers and analysis tools to treat differently postconditions and these sorts of specifications for unit tests. As a side note, notice that, although not needed in the example above, it will in general be necessary to use attribute 'Old to refer to the pre-state of the call, like in: procedure Sqrt (X : in out Integer) with Test => if X'Old > 100 then X >= 10; I was told that the "with Blah => ..." syntax is meant to be more-or-less equivalent to "for ...'Blah use ...". Then, allowing multiple aspects of the same kind could require that such aspects are named in some way, so that you can access them in the code with 'Blah("name")? As Bob suggested that I submit an exact wording, I'll only propose for now: "Unless specified otherwise for a specific aspect_mark, more than one occurrence of each aspect_mark is allowed within a single aspect_specification." **************************************************************** From: Yannick Moy Sent: Tuesday, April 27, 2010 11:38 AM I'll answer my own question, thanks to an idea that Cyrille Comar gave me. He proposed that we use different identifiers for different aspects of the same kind that apply to the same declaration, so that the Sqrt example I gave in my previous email would read: function Sqrt (X : Integer) return Integer with Test_1 => if X > 100 then Sqrt'Result >= 10, Test_2 => if X < 100 then Sqrt'Result < 10, Test_3 => if X = 100 then Sqrt'Result = 10, Test_4 => Sqrt'Result >= 0; This is already allowed in the current wording, and it fits our needs well, so please ignore the previous request for allowing multiple user aspects of the same kind within a single aspect_specification. **************************************************************** From: Tucker Taft Sent: Wednesday, April 28, 2010 2:19 AM Here is an update to the AI on aspect specifications. Comments welcome. (yeah, right ;-) [This is version /03 of the AI - Editor.] **************************************************************** From: Bob Duff Sent: Wednesday, April 28, 2010 6:32 PM > Here is an update to the AI on aspect specifications. > Comments welcome. (yeah, right ;-) ;-) Looks great. Thanks. I think we need an Impl Perm to add impl-def aspects. > !subject Aspect Specifications > [AARM NOTE: The aspect_specification is an optional element in the following > kinds of declarations: > * object_declaration; > * full_type_declaration; > * subtype_declaration; > * component_declaration; > * subprogram_declaration; > * abstract_subprogram_declaration; > * null_procedure_declaration; > * package_declaration; > * private_type_declaration; > * private_extension_declaration; > * task_type_declaration; > * single_task_declaration; > * protected_type_declaration; > * single_protected_declaration; > * entry_declaration; > * generic_declaration.] It would be useful to list all the kinds of declarations that do not allow aspect_specs. I suppose they're not allowed on bodies, even if the body acts as a spec (subps). > Name Resolution > > The expected type for an expression associated with a given > aspect_mark is the type of the identified aspect of the entity defined > by the associated declaration (the *associated entity*). The names in > such an expression [Redundant: are not resolved at the point of the > associated declaration, but rather] are resolved at the end of the > immediately enclosing declaration list or at the first freezing point > of the associated entity, whichever comes first. > > If the associated declaration is for a subprogram or entry, the names of the > formal parameters are visible within the expression, as are certain > attributes, as specified elsewhere in this International Standard for > the identified aspect. If the associated declaration is a type_declaration, > within the expression the names of any components are visible, and the > name of the first subtype denotes the current instance of the type (see 8.6). I think you want "directly visible" above. We need "current instances" for subtypes, too: subtype Nonzero is Integer with Predicate => Nonzero /= 0; > function Union(X, Y : Set) return Set > is abstract with > Post'Class => > Count(Union'Result) = Count(X) + Count(Y); I think "<=" would be more correct than "=" in this example. > This presumes that aspect identifiers generally match attribute names > or pragma names. However, particularly in the case of pragmas, we may > prefer to choose nouns rather than adjectives for aspect names, so the > names work better after the preposition "with". Hence, perhaps > "Atomicity" or "Independence" rather than "Atomic" and "Independent." I'm not sure what my opinion is on this. I'm sure we can discuss it endlessly. "with Pack" looks funny, but it's a simple rule to say that it matches the pragma name. **************************************************************** From: Randy Brukardt Sent: Wednesday, April 28, 2010 6:44 PM > I'm not sure what my opinion is on this. I'm sure we can discuss it > endlessly. "with Pack" looks funny, but it's a simple rule to say > that it matches the pragma name. The current Ada aspect name for pragma Pack is "Packing". Ada 95 explicitly defined this (not sure why). So we have "with Packing =>", not "with Pack". Most of the others don't have names, however. The question of whether to bother giving them names probably is an endless pit, as you suggest. **************************************************************** From: Bob Duff Sent: Wednesday, April 28, 2010 7:15 PM We can have "with Packing" or "with Pack", (with or without "=> True") as we wish. Or even "with Packed" or "with Packedness". ;-) I think the "packing" in 13.2: A pragma Pack specifies the packing aspect of representation; the type (or the extension part) is said to be packed. is my handiwork. It's not cast in stone. I think I just wanted it to fit in with whatever rule forbids specifying the same aspect twice. > Most of the others don't have names, however. The question of whether > to bother giving them names probably is an endless pit, as you suggest. So let's defer that discussion, and concentrate on more important things, like "Are there any decls that don't allow aspect_clauses, and if so, is there a good reason, or just because we forgot about them?" What about formal params? **************************************************************** From: Randy Brukardt Sent: Wednesday, April 28, 2010 7:34 PM > What about formal params? I don't think we want those; it would require new kinds of generic matching. And we don't allow rep clauses or operational clauses on them now; why change that? **************************************************************** From: Tucker Taft Sent: Wednesday, April 28, 2010 7:34 PM > ... > So let's defer that discussion, and concentrate on more important > things, like "Are there any decls that don't allow aspect_clauses, and > if so, is there a good reason, or just because we forgot about them?" > > What about formal params? And discriminants. And loop indices. I didn't include those, but I don't have a strong feeling either way. Putting them on formals does add complexity to conformance. I guess my instinct would be to leave them off, and rely on putting them on subtypes rather than individual parameters or discriminants. Randy is right we need to address static matching of subtypes. It seems we could allow matching when the same aspects are specified with equal static expressions. Alternatively, don't provide static matching at all if the two subtypes have different sets of aspect_specifications applying to them (include even "confirming" aspect_specifications). **************************************************************** From: Tucker Taft Sent: Wednesday, April 28, 2010 7:53 PM Actually I did allow them on generic formal parameters, but not on subprogram formals. They seem like they might be important on generic formals, but I agree they will need some generic matching rules if we allow them. At this point we can simply say that matching rules are specific to each aspect that is allowed on a generic formal. **************************************************************** From: Randy Brukardt Sent: Wednesday, April 28, 2010 8:03 PM That might be OK, but then we'll have to check every existing aspect for whether or not we need to add wording about this case. Which I don't find very appealing, because I know who will get stuck with the job. :-) **************************************************************** From: Bob Duff Sent: Wednesday, April 28, 2010 8:13 PM > > What about formal params? > > I don't think we want those; ... I'm not saying we want those. I'm just saying we want to think about whether we want those. And I'd like to have a complete list of which ones need thinking about. (I have an uneasy feeling I'm going to be assigned the task of coming up with that complete list. Sigh. I guess that's fair.) >... it would require new kinds of generic matching. > And we don't allow rep clauses or operational clauses on them now; why >change that? Well, I recall Robert griping that pragmas are not allowed in formal parts. I don't remember the context, but I guess it's related. **************************************************************** From: Randy Brukardt Sent: Wednesday, April 28, 2010 10:02 PM > Here is an update to the AI on aspect specifications. > Comments welcome. (yeah, right ;-) Wording that appears to be missing based on the minutes of the St. Pete meeting: (1) List of declarations that these are *not* allowed on. It appears currently to be renames and bodies. Explain any missing ones. (2) How does this relate to conformance and static matching? It seems to be ignored for subprograms (if it isn't on the body); do we need to say that somewhere? Probably need an AARM note even if nothing else changes. Static matching surely needs wording (even if to put it off to the individual aspects). (3) There is no wording explaining what identifier an "aspect_mark" is. We've put this off, we need an actual answer. (I've always assumed it was the aspect names, which are fully defined by the language now, but in any case there needs to be wording to say that. I cannot find any now.) (4) Unrecognized aspects are an error; something needs to be said about this. (5) We need a standard style for introducing new aspects. That probably should be mentioned in the !discussion of this one. (6) We want to add an index of aspects that can be used here. That probably could be another AI (someone needs to propose that formally). **************************************************************** From: Randy Brukardt Sent: Wednesday, April 28, 2010 10:21 PM > I'm not saying we want those. I'm just saying we want to think about > whether we want those. And I'd like to have a complete list of which > ones need thinking about. > > (I have an uneasy feeling I'm going to be assigned the task of coming > up with that complete list. Sigh. I guess that's fair.) Bob, come up with that complete list! :-) Seriously, given Tucker's difficulty in finding time to do things, it would be best if the rest of us pitched in on "easy" things, which this appears to be. So go for it. > >... it would require new kinds of generic matching. > > And we don't allow rep clauses or operational clauses on > them now; why > >change that? > > Well, I recall Robert griping that pragmas are not allowed in formal > parts. I don't remember the context, but I guess it's related. I also recall that we convinced him that it was a bad idea, and we didn't do anything about it (I believe you can find the mail in the second AI about pragma placement). I'm against allowing these on any kind of formal parameter; we don't allow any such things currently on any of the things Tucker listed (subprogram formal parameters, discriminants, loop parameters, etc.) and it would be a significant amount of work to change that. (Do you want people to specify how many bits you can use to pass a parameter? I didn't think so.) I'm also against allowing it on generic formal parameters, for similar reasons. Plus the massive number of generic matching rules that would be needed. I suppose it would be OK to say: Unless otherwise specified, aspects cannot be given on generic formals. So that it is illegal unless something really needs it and then specifies what it means. I surely don't want to be doing matching of preconditions for formal subprograms!! **************************************************************** From: Bob Duff Sent: Monday, May 10, 2010 2:25 PM This is my response to this homework item: AI05-0183-1: Work with Tucker on a list of declarations that don't allow aspect_specifications, and why not. which was assigned to me at the April 29 telephone meeting. I'm not sure about the "why not" part. There is a list of declarations that include aspect_spec in the !proposal, and again in the AARM. The latter is missing generic_formal_parameter_declaration. It's also missing from the syntax rules. Seems like it should be included. I suggest putting the list only in the AARM, and put something like this in the proposal: The aspect_specification is an optional element allowed by the syntax rules for many kinds of declarations. Here's the list: * object_declaration; * full_type_declaration; * subtype_declaration; * component_declaration; * subprogram_declaration; * abstract_subprogram_declaration; * null_procedure_declaration; * package_declaration; * private_type_declaration; * private_extension_declaration; * task_type_declaration; * single_task_declaration; * protected_type_declaration; * single_protected_declaration; * entry_declaration; * generic_declaration; * generic_formal_parameter_declaration. [What about renaming declarations?] I did not carefully review the syntax rules in the AI to see if they in fact match the above list. Here's a list of all the kinds of declaration, with "*" marking the ones mentioned above, and NO marking the ones that currently do not allow an aspect_specification. basic_declaration type_declaration full_type_declaration* ... task_type_declaration* protected_type_declaration* incomplete_type_declaration -- NO private_type_declaration* private_extension_declaration* subtype_declaration* object_declaration* ... single_task_declaration* single_protected_declaration* number_declaration -- NO subprogram_declaration* abstract_subprogram_declaration* null_procedure_declaration* package_declaration* renaming_declaration -- NO exception_declaration -- NO generic_declaration* generic_instantiation -- NO enumeration_literal_specification -- NO discriminant_specification -- NO component_declaration* loop_parameter_specification -- NO parameter_specification -- NO subprogram_body -- NO entry_declaration* entry_index_specification -- NO choice_parameter_specification -- NO generic_formal_parameter_declaration* (or NO -- not clear) extended_return_statement -- NO I guess we should add renaming_declaration and exception_declaration. I guess generic_formal_parameter_declaration should be included. It seems a little odd to allow component_declaration, but not discriminant_specification. Not sure about parameter_specification. Please discuss. When that's done, we should add AARM text after the list of declarations that allow it, like: The syntax rules do not allow aspect_specifications on the other kinds of declarations, which are: ... (list them) Also, aspect_specifications are not allowed on bodies or accept statements, even though these things are sort of like declarations, and in the case of subprogram_bodies can actually be declarations. If you want an aspect_specification on a subprogram, you have to give an explicit declaration before the body. **************************************************************** From: Gary Dismukes Sent: Monday, May 10, 2010 7:09 PM > I guess we should add renaming_declaration and exception_declaration. I agree those should be included. > I guess generic_formal_parameter_declaration should be included. Dunno. Doesn't that get into matching complexities? > It seems a little odd to allow component_declaration, but not > discriminant_specification. Not sure about parameter_specification. It does seem inconsistent to disallow them for discriminants. Is there any significant argument for not allowing them on discriminants and parameter specs? I suppose it tends to interfere with readability, plus there's the issue of conformance for spec/body and multipart declarations. **************************************************************** From: Tucker Taft Sent: Monday, May 10, 2010 9:12 PM I am reluctant to allow specifying aspects on a renaming declaration. That could really confuse the model and add a lot of complexity to handling renames, which are already pretty tricky. I agree that exception declarations should allow aspect specifications. Randy suggested that by default, aspect specifications would not be permitted on generic_formal_parameter_decls, but that they could be permitted for particular aspects. We would have to define the matching rules for any aspects that we allow being specified on a generic formal. But it seems like it could be useful at least in some cases. Allowing them on discriminants or parameters definitely adds complexity to conformance rules. It doesn't seem so odd that discriminants are special, since they have other unique properties, such as being read-only, and being specifiable in a subtype indication, etc. **************************************************************** From: Jean-Pierre Rosen Sent: Tuesday, May 11, 2010 1:44 AM > I am reluctant to allow specifying aspects on a renaming declaration. > That could really confuse the model and add a lot of complexity to > handling renames, which are already pretty tricky. I agree that > exception declarations should allow aspect specifications. I fully agree here. Aspects are a property of the entity, not of the view. We already have the problem that constraints on the subtype of a renaming are ignored, let's not make it worse. **************************************************************** From: Bob Duff Sent: Tuesday, May 11, 2010 8:46 PM > I am reluctant to allow specifying aspects on a renaming declaration. > That could really confuse the model and add a lot of complexity to > handling renames, which are already pretty tricky. If we have no aspects that are specifiable on renames, we could still allow the syntax, just in case an implementation wants to do it for an impl-def aspect. Then whatever complexity there is belongs to the implementer. Renames can be dispatching ops. So you can't put a precondition on one? Hmm... >...I agree that exception declarations > should allow aspect specifications. > > Randy suggested that by default, aspect specifications would not be > permitted on generic_formal_parameter_decls, but that they could be > permitted for particular aspects. But that's true for everything. That is, we define the syntax to allow aspect_specs on certain decls. Then, for each aspect, we say "this is allowed on so-and-so decls". If there are no language-defined aspects that are allowed on generic_formal_parameter_decls, we can still allow the syntax. > We would have to define the matching rules for any aspects that we > allow being specified on a generic formal. If there are no language-defined ones, we can let implementers worry about that. >...But it seems like it could be useful at least in some cases. > > Allowing them on discriminants or parameters definitely adds > complexity to conformance rules. It doesn't seem so odd that > discriminants are special, since they have other unique properties, > such as being read-only, and being specifiable in a subtype > indication, etc. Again, all the complexity can be placed on the implementer, if all we do is allow the syntax. On the other hand, the syntax gets pretty ugly in these cases. I don't feel strongly about any of this, except that I strongly believe we should have a list in the AARM of the decls (and bodies) that don't allow aspects syntactically, so we can be sure we did it deliberately. I suggested wording in my previous e-mail. **************************************************************** From: Randy Brukardt Sent: Wednesday, May 19, 2010 10:14 PM > This is my response to this homework item: > > AI05-0183-1: Work with Tucker on a list of declarations that don't > allow aspect_specifications, and why not. > > which was assigned to me at the April 29 telephone meeting. > I'm not sure about the "why not" part. I think you were supposed to explain why each basic declaration that doesn't allow aspect clauses doesn't allow aspect clauses. (I can't think of any way to say this that isn't redundant!) Maybe it would be better to say that there needs to be an explanation for each declaration on the list of declarations that don't allow aspect_clauses -- the idea being that the default is that they *are* allowed. This seems like useful information for the AARM. **************************************************************** From: Bob Duff Sent: Friday, May 20, 2010 7:07 AM Right, I understood that, and my "I'm not sure..." comment was meant to mean "I don't know the answer to those questions". I'm the one who raised the issue, and I'm happy with just having the list, so I can look at it and say "yeah, OK, seems reasonable I guess". If Tuck can put coherent reasons on them, that's fine too. **************************************************************** From: Randy Brukardt Sent: Wednesday, May 19, 2010 10:24 PM > > Randy suggested that by default, aspect specifications would not be > > permitted on generic_formal_parameter_decls, but that they could be > > permitted for particular aspects. > > But that's true for everything. That is, we define the syntax to > allow aspect_specs on certain decls. Then, for each aspect, we say > "this is allowed on so-and-so decls". Sadly, we don't do a good job of that for the existing aspects in Ada 95 and 2005. However, the rule added by AI05-0106-1 (13.1(9.2/3)) should cover it, so we don't need any additional wording for this AI. **************************************************************** From: Bob Duff Sent: Friday, May 14, 2010 8:08 AM I think AI05-0183-1 (Aspect Specifications) needs some verbiage about visibility. In particluar, this (from Yannick's recent ada-comment@ e-mail): type Part (Max_Players : Positive) is record ... Num_Players : Positive; -- Number of players Pos : Positions (1 .. Max_Players); -- Position of each player end record with Predicate => Num_Players in 1 .. Max_Players; should be legal. So should this: with Predicate => Part.Num_Players in 1 .. Part.Max_Players; **************************************************************** From: Tucker Taft Sent: Monday, June 7, 2010 2:58 PM Here is an update to the aspect specification AI. [This is version /04 - Editor.] There are still some things missing, such as the Annex of specifiable aspects. I am also a little unclear how we should indicate in the body of the RM (as opposed to in the eventual annex) which aspects can be specified. My guess is that all specifiable attributes should be specifiable using an aspect_specification. But it is not clear which pragmas nor which of the other aspects associated with record and enum rep clauses should be specifiable with an aspect_specification. **************************************************************** From: Randy Brukardt Sent: Thursday, June 10, 2010 9:22 PM > Here is an update to the aspect > specification AI. There are still > some things missing, such as the > Annex of specifiable aspects. I am > also a little unclear how we should > indicate in the body of the RM > (as opposed to in the eventual annex) > which aspects can be specified. So are the rest of us! Someone needs to invent something, and you're one of the best inventors. > My guess is that all specifiable attributes should be specifiable > using an aspect_specification. > But it is not clear which pragmas nor > which of the other aspects associated > with record and enum rep clauses should be specifiable with an > aspect_specification. I think a straw-man here would be helpful. I'm not even sure that most of us are considering everything that might be possible to specify. So I think it would be helpful if you would make a stab at figuring how these things might work. (But only after the rest of your homework is done, the two remaining AIs are more important than these details of this one.) **************************************************************** From: Christoph Grein Sent: Tuesday, September 28, 2010 2:33 AM 6.7(2/3) null_procedure_declaration ::= [overriding_indicator] procedure_specification is null [aspect_specification];; Additional semicolon at end. [Editor's note: This is a typo in the draft AARM.] 13.3.2 (16/3) ... a precondition check is performed. This begins with the evaluation of the precondition expressions that apply to the subprogram or entry... The order of performing the checks is not specified, ... Does it make sense to say with which check the evaluation begins without saying what then follows, and at the same time specifying that the sequence of checks is unspecified? (No further comments since the chapters 13.3.1 and 2 are incomplete. **************************************************************** From: Randy Brukardt Sent: Tuesday, September 28, 2010 9:00 PM Probably not. The additional of "begins" doesn't seem to add anything here; the rest of it says what's done with the results of the evaluation and makes it clear that they all might not be evaluated. The wording probably would be better to just say "The check evaluates the precondition expressions..." or even "This evaluates...". **************************************************************** From: Tucker Taft Sent: Monday, October 25, 2010 2:55 PM Here is a relatively minor update to AI05-0183-1. [This is version /06 of the AI.] I added a requirement that all usage_names that appear in an aspect_definition resolve to the same thing if freezing happens before the end of the declaration list, along with an example in the !discussion. I added some general statements about attribute-defs and pragmas that can be replaced by aspect_specs. I made some other minor fixes as requested in the minutes. **************************************************************** From: Robert Dewar Sent: Monday, October 25, 2010 3:13 PM > If the freezing point comes before the end of the enclosing > declaration list, we require the usage names in the aspect_definition > to resolve to the same entities at the two places. Because there is > no explicit indication of where a freezing point occurs in the source, > we felt it would be too confusing if we didn't require this. I really have NO idea how to implement this without a major earthquake. I think we will just leave this unimplemented in GNAT and not bother with it. At this stage ACATS tests are merely useful tools anway, formal validation has entirely disappeared as an issue. Perhaps Ed has some ideas. **************************************************************** From: Tucker Taft Sent: Monday, October 25, 2010 3:19 PM Did you take a look at the example in the !discussion? It does seem pretty convincing (at least to me) that this is a legitimate concern. Here it is again. === If the freezing point comes before the end of the enclosing declaration list, we require the usage names in the aspect_definition to resolve to the same entities at the two places. Because there is no explicit indication of where a freezing point occurs in the source, we felt it would be too confusing if we didn't require this. This means that if a freezing point "moves" and thereby crosses over, for example, the overriding of an inherited subprogram (of a non-tagged type), the compiler would complain rather than silently reinterpreting the name in the aspect_definition. For example: type New_T is new T with Type_Invariant => Is_Valid(New_T); Default_Obj : New_T; -- Here we freeze New_T function Is_Valid(Y : New_T) return Boolean; -- Here we override Is_Valid private -- Here we reach the end of the declaration list. In a case like this, the user almost certainly wants to refer to the overriding of Is_Valid, but since the freezing happens before the overriding, without the rule to require that the names in the aspect_definition resolve to the same thing, they would not get what they expected. With this rule, the compiler would complain, and the user would (hopefully ;-) realize they need to move the declaration of Default_Obj down a little further so Is_Valid can be overridden first. **************************************************************** From: Robert Dewar Sent: Monday, October 25, 2010 3:54 PM Are these things really called Type_Invariant, rather than just Invariant? I don't really mind, but it is a pain to change and I prefer the shorter name anyway. **************************************************************** From: Robert Dewar Sent: Monday, October 25, 2010 3:55 PM > Did you take a look at the example in the !discussion? > It does seem pretty convincing (at least to me) that this is a > legitimate concern. Here it is again. I think whenever you cause a major impossible pain to an existing implementation (Ed agrees with me that this is that category), then you have to be sure it is worth it. To recall, for Ada 95, we went out of our way to accomodate displays because one implementation demanded it, despite the fact that it a) really damaged expressive power b) turned out to be quite unnecessary, the one implementation involved never made it to Ada 95 anyway. I don't think this begins to be in the category of critical things that are worth causing major pain to an implementation (especially considering that you can't really do that any more, implementations will just ignore things they can't implement, especially when it is just a matter of diagnosing unexpected behavior). To me this is more in the warning category anyway I would just settle for implementation advice that says it is desirable to warn in this situation. Yes, I see the example, but as I say, it is more a case where a warning is more appropriate anyway, I am always nervous when I see a language designer say "the user almost certainly wants to ..." which is more likely worth a warning if true. In this case, what GNAT could do, and actually it seems a good idea, is to have optional information messages that say "warning: Invariant expression from line 12 is resolved here" "warning: since type& is frozen here" **************************************************************** From: Brad Moore Sent: Friday, November 12, 2010 8:24 AM > Well, I did say I only had brief glimpses but it did seem that there was the > risk of confusion with multiple use of with. I'm wondering if it's a bit messy that the aspect syntax for a package declaration ends up being quite different than the aspect syntax for a package instance declaration. In the first case, the aspects come immediately before the "is", and in the second case they comes a long ways after the "is". This is the reason my previous example had the incorrect syntax. I had mistakenly assumed that aspects for all package declarations came before the "is". I wonder how many others will make that same mistake. Instead of writing; package P1 with Pure is end P1; package P2 is new P3 with Pure; Would it be better to write? package P1 with Pure is end P1; package P2 with Pure is new P3; In the case of the instantiation, it seems clearer to me that the Pure attribute is now being associated with the new package, rather than somehow being associated with the original package. If package declarations are a special case for aspect syntax, maybe package instance declarations should be lumped into that special case as well. I suppose one might argue that its better to limit the special case as much as possible, rather than have it creep into other syntax forms. On the other hand, maybe all aspect clauses should come before the "is", This would eliminate the special case, and might make things more consistent. Some examples ... full_type_declaration example------------------------- type T1 (Length : Integer) with pack is record S : String (1 .. Length); end record; instead of type T1 (Length : Integer) is record S : String (1 .. Length); end record with pack; task type declaration aspects already come before the is ----------- protected type declaration aspects already come before the is --------- private type declaration example --------------------- type T1 (Length : Integer) with pack is limited private; instead of type T1 (Length : Integer) is limited private with pack; private extension declaration example ------------------- type T1 (Length : Integer) with pack is new limited T2 with private; instead of type T1 (Length : Integer) is new limited T2 with private with pack; (I find these last two examples particularly compelling. The fact that this is an incomplete declaration can get lost in the declaration. I think private should be the last word) object declarations don't have an is --------------------- function and procedure specifications don't have an is ------------- This is not an exhaustive list of examples, but I don't see any others offhand that would be problematic. In many cases I find the declarations read better having the aspect come before the is. **************************************************************** From: Robert Dewar Sent: Friday, November 12, 2010 8:32 AM > I'm wondering if it's a bit messy that the aspect syntax for a package > declaration ends up being quite different than the aspect syntax for a > package instance declaration. In the first case, the aspects come > immediately before the "is", and in the second case they comes a long > ways after the "is". This is the reason my previous example had the > incorrect syntax. I had mistakenly assumed that aspects for all > package declarations came before the "is". I wonder how many others > will make that same mistake. Actually GNAT has this wrong, and it is a huge pain, because it means you have to get all the way through the aspects then start looking at what is after IS, to know that the aspects you have parsed do not belong there. This is really messy. I agree with Brad, this is confusing, I would always put the aspects before IS for all the program unit type syntax. **************************************************************** From: Tucker Taft Sent: Friday, November 12, 2010 8:52 AM I agree that the placement of the aspect specification is a bit tricky. I actually found the placement before the "is new" quite jarring. But it is annoying that the placement jumps around depending on the construct. The one that seems hardest for me to remember is the one for a record type. The general rule is that it comes just before the ";" except for a non-instance package specification, task declaration, or protected declaration, where it comes just before the "is". **************************************************************** From: Bob Duff Sent: Friday, November 12, 2010 9:07 AM > In many cases I find the declarations read better having the aspect > come before the is. Hmm. I think I agree. The "with private with Pack" syntax seems particularly odd. **************************************************************** From: Stephen Michell Sent: Friday, November 12, 2010 11:07 AM Good catch Brad. I think that you explained that well. **************************************************************** From: Tucker Taft Sent: Friday, November 12, 2010 11:26 AM What about "type T is new Integer;"? Or "procedure Foo(X: Integer) is null;". And what about "renames"? Is "renames" like "is"? Not an easy choice... On the other hand, once we make it, the compiler will help us all learn what is the right way to do it. ;-) I think I still somewhat prefer seeing aspect specifications at the end unless that is ridiculously far away as in a non-instance package spec. This is especially true if they start getting complex, as in: with Dynamic_Predicate => Sorted_Arr_Type(Arr_Type'First) <= Sorted_Arr_Type(Arr_Type'Last) This seems like something that doesn't want to be interspersed in the middle of an array type definition. **************************************************************** From: Randy Brukardt Sent: Friday, November 12, 2010 4:30 PM > What about "type T is new Integer;"? > Or "procedure Foo(X: Integer) is null;". > And what about "renames"? Is "renames" like "is"? The last isn't possible: we don't allow aspects on renames. (Aspects are the same as those from the renamed object, since they're not view-specific.) **************************************************************** From: Robert Dewar Sent: Saturday, November 13, 2010 5:26 AM > What about "type T is new Integer;"? No one is suggesting the change here, don't use it as a strawman. > Or "procedure Foo(X: Integer) is null;". No one is suggesting the change here, don't use it as a strawman. > And what about "renames"? Is "renames" like "is"? No, it isn't, no one has suggested that either. The suggestion is simply to treat the unit cases differently and uniformly. > I think I still somewhat prefer seeing aspect specifications at the > end unless that is ridiculously far away as in a non-instance package > spec. > This is especially true if they start getting complex, as in: > > with Dynamic_Predicate => > Sorted_Arr_Type(Arr_Type'First)<= Sorted_Arr_Type(Arr_Type'Last) > > This seems like something that doesn't want to be interspersed in the > middle of an array type definition. No one is suggesting interspersing this, don't use it as a strawman :-) The suggesting is that we should have uniform treatment for package pack is bla; regardless of what bla is, and I think that's a real improvement over what you propose. To me it is just weird (to the parser and to a human reader to have) package pack with lots of aspects is and still not know if the aspects belonged there. It's not hard to implement in the parser of course, but it's a real oddity to treat these cases differently, and will surely cause confusion. **************************************************************** From: Robert Dewar Sent: Saturday, November 13, 2010 5:27 AM >> What about "type T is new Integer;"? >> Or "procedure Foo(X: Integer) is null;". >> And what about "renames"? Is "renames" like "is"? > > The last isn't possible: we don't allow aspects on renames. (Aspects > are the same as those from the renamed object, since they're not > view-specific.) Personally I would prefer the rule to be that we allow aspects, but none of the language ones can be used for renamings, since that allows useful use of the notation for implementation defined aspects, but it's not a big deal, and if we have an arbitrary limitation that prevents this, we can live with it. **************************************************************** From: Bob Duff Sent: Saturday, November 13, 2010 7:50 AM > Personally I would prefer the rule to be that we allow aspects, but > none of the language ones can be used for renamings, since that allows > useful use of the notation for implementation defined aspects, ... I agree. >...but it's not a > big deal, and if we have an arbitrary limitation that prevents this, >we can live with it. That, too. **************************************************************** From: Bob Duff Sent: Saturday, November 13, 2010 7:44 AM > > What about "type T is new Integer;"? > > No one is suggesting the change here, don't use it as a strawman. ... > The suggestion is simply to treat the unit cases differently and > uniformly. Brad's suggestion goes further than that, so I don't see any "straw men" from Tucker. **************************************************************** From: Brad Moore Sent: Saturday, November 13, 2010 10:42 AM > The general rule is that it comes just before the ";" except for a > non-instance package specification, task declaration, or protected > declaration, where it comes just before the "is". There is something to be said though, for simpler rules being easier to memorize. E.g. It always comes before "is", otherwise comes before ";" > What about "type T is new Integer;"? I find this to be a similar case to the package instantiation declaration. If the aspects are at the end, it might be confusing for a novice because one might think the aspects are somehow defining requirements on the base type. If they come after the type name it is clearer that they apply to the new type. eg. type T is new Foo with Atomic; vs type T with Atomic is new Foo; > Or "procedure Foo(X: Integer) is null;". I find this case to be similar to the private type and private extension case. The important part of the declaration is that it is a null procedure. If the aspects at the end, the "is null" might get lost in the text. eg. procedure Foo (C : Class; X : in out Integer) is null with Pre'Class => X = 0, Post'Class => X > 0; vs procedure Foo (C : Class; X : in out Integer) with Pre'Class => X = 0, Post'Class => X > 0 is null; > And what about "renames"? Is "renames" like "is"? According to the latest version of AI 183, aspects are not permitted on renaming declarations. Is that still correct? > I think I still somewhat prefer seeing aspect specifications at the > end unless that is ridiculously far away as in a non-instance package > spec. > This is especially true if they start getting complex, as in: > > with Dynamic_Predicate => > Sorted_Arr_Type(Arr_Type'First) <= Sorted_Arr_Type(Arr_Type'Last) > > This seems like something that doesn't want to be interspersed in the > middle of an array type definition. I share your concern. It might end up looking weird if it appears that a bunch of code occurs in the middle of a declaration. type Sorted_Arr_Type is array (Integer range <>) of Foo with Dynamic_Predicate => Sorted_Arr_Type(Arr_Type'First) <= Sorted_Arr_Type(Arr_Type'Last) ; vs type Sorted_Arr_Type with Dynamic_Predicate => Sorted_Arr_Type(Arr_Type'First) <= Sorted_Arr_Type(Arr_Type'Last) is array (Integer range <>) of Foo; The first version is more pleasing to my eye, though the second isn't horrible. I think I like the first better in this case, because it fits better on 3 lines. The second one "looks" bigger. With shorter aspects, I find my preference goes the other way. eg I like type Sorted_Arr_Type with Atomic_Components is array (Integer range <>) of Foo; better than type Sorted_Arr_Type is array (Integer range <>) of Foo with Atomic_Components; Probably to convince ourselves one way or the other, we need to look at a more complete set of examples. **************************************************************** From: Tucker Taft Sent: Saturday, November 13, 2010 10:44 AM >>> What about "type T is new Integer;"? >> >> No one is suggesting the change here, don't use it as a strawman. > ... >> The suggestion is simply to treat the unit cases differently and >> uniformly. > > Brad's suggestion goes further than that, so I don't see any "straw > men" from Tucker. Correct. I was reacting to Brad's suggestion that we move *all* aspect_specifications before the "is", including on "normal" type definitions. I understand Brad's motivation, but I was illustrating why I think it would be unwise. As far as package instantiations, I can see accept it either way, though I did react somewhat negatively when I first saw it before the "is new". I presume we are not allowing aspect specifications on bodies. If we were, then I would wonder where the aspect_specification should go on: procedure Blubber(...) is null/abstract; Before the "is" or before the ";". Ditto for a subprogram instantiation. **************************************************************** From: Jean-Pierre Rosen Sent: Saturday, November 13, 2010 10:55 AM > I find this to be a similar case to the package instantiation declaration. > If the aspects are at the end, it might be confusing for a novice > because one might think the aspects are somehow defining requirements > on the base type. If they come after the type name it is clearer that > they apply to the new type. > > eg. > > type T is new Foo with Atomic; > > vs > > type T with Atomic is new Foo; I prefer the first one, because I read it as "type T is a foo, with an extra property: it is atomic". [...] > Probably to convince ourselves one way or the other, we need to look > at a more complete set of examples. I fully agree with that statement! **************************************************************** From: Robert Dewar Sent: Saturday, November 13, 2010 8:23 PM > Brad's suggestion goes further than that, so I don't see any "straw > men" from Tucker. I had not realized that Brad was suggesting type x is array with size => 64 of ... I find that suggestion ludicrous, are you really sure Brad was suggesting this? **************************************************************** From: Robert Dewar Sent: Saturday, November 13, 2010 8:28 PM > type T is new Foo with Atomic; > > vs > > type T with Atomic is new Foo; So Brad really *was* suggesting this. Apologies for the straw man comment to Tuck. Well I think it is simply horrible to read, and do not support this change at all. > eg. > > procedure Foo (C : Class; X : in out Integer) > is null > with Pre'Class => X = 0, Post'Class => X> 0; vs > procedure Foo (C : Class; X : in out Integer) > with Pre'Class => X = 0, Post'Class => X> 0 > is null; Again, IMO horrible! I really dislike putting aspects before the IS in these cases. > Probably to convince ourselves one way or the other, we need to look > at a more complete set of examples. Except for the package case which we are still discussing, I think we have a fine set of rules now, and I see no significant argument for changing them. **************************************************************** From: Robert Dewar Sent: Saturday, November 13, 2010 8:29 PM > Correct. I was reacting to Brad's suggestion that we move *all* > aspect_specifications before the "is", including on "normal" type > definitions. I understand Brad's motivation, but I was illustrating > why I think it would be unwise. I 100% agree with you Tuck on this! **************************************************************** From: Brad Moore Sent: Saturday, November 13, 2010 10:03 PM >> type T is new Foo with Atomic; >> >> vs >> >> type T with Atomic is new Foo; > > So Brad really *was* suggesting this. Apologies for the straw man > comment to Tuck. Well, I actually had two independent suggestions. One was just do deal with the package instantiation case, and the other was a more general suggestion as an attempt to bring a more consistent approach with regard to aspect placement when "is" is present. For the package instantiation case, you convinced me a while back that the aspect on a package declaration has to come before the "is". That suggests to me that to do anything about the package instantiation case, the aspect would likely also have to come before the "is", unless someone comes up with a better idea. Just curious though, Do you also prefer type T is new Foo with private with pack; over type T with pack is new Foo with private; Having two with's connected together with very different meaning seems like it could be a source of confusion, and I imagine might be awkward to explain to a class of Ada 101 students. Maybe it would be nice if we could combine the two with's into one, and treat private as a sort of pseudo-aspect for private types and private extensions. eg. type T is new Foo with private, pack; I suspect that I've already stirred up enough with my previous suggestions. I think I better put on my asbestos suit and crash helmet.... :-) **************************************************************** From: Robert Dewar Sent: Sunday, November 14, 2010 9:58 AM (grab flame thrower!) > For the package instantiation case, you convinced me a while back that > the aspect on a package declaration has to come before the "is". That > suggests to me that to do anything about the package instantiation > case, the aspect would likely also have to come before the "is", > unless someone comes up with a better idea. It doesn't *have* to come before the IS, I slightly prefer that it does, but can live with Tuck's viewpoint, and the latter has the advantage of being the status quo! > Just curious though, > > Do you also prefer > > type T is new Foo with private with pack; Yes, I prefer this consistent form, even though depending how you write it, it could be confusing, for me, the format would always be type T is new Foo with private with Pack => True; BTW I think I *do* prefer to keep the => True possibility (again has the advantage of being the status quo), precisely because it makes it very clear that you are talking about the aspect case syntactically. I would not insist on it, but I would usually use it I think in a case like this. > over > > type T with pack is new Foo with private; > > Having two with's connected together with very different meaning seems > like it could be a source of confusion, and I imagine might be awkward > to explain to a class of Ada 101 students. I doubt this (illegal) form would be a likely discussing item in Ada 101, and I really don't think it's such a problem anyway. > Maybe it would be nice if we could combine the two with's into one, > and treat private as a sort of pseudo-aspect for private types and > private extensions. > > eg. > > type T is new Foo with private, pack; Absolutely not, this is a gratitous and troublesome change in existing syntax. > I suspect that I've already stirred up enough with my previous suggestions. > I think I better put on my asbestos suit and crash helmet.... :-) suit up! **************************************************************** From: Randy Brukardt Sent: Monday, November 15, 2010 4:15 PM ... > Well, I actually had two independent suggestions. > > One was just do deal with the package instantiation case, and the > other was a more general suggestion as an attempt to bring a more > consistent approach with regard to aspect placement when "is" is > present. > > For the package instantiation case, you convinced me a while back that > the aspect on a package declaration has to come before the "is". That > suggests to me that to do anything about the package instantiation > case, the aspect would likely also have to come before the "is", > unless someone comes up with a better idea. I sympathize with this position. But keep in mind that presuming that we leave aspect clause placement for subprograms as it is, we have a nasty problem with instances, in that they are used both for subprograms and packages. (And I'm presuming that subprograms are left as is since the current syntax reads the best for Pre and Post.) Given that subprograms are written thus: procedure Pro (A, B : in Integer) with Pre => A > B; and packages are written thus: package Pack with Pure => True is ... we have three choices for instantiations: (1) Always at the end (like subprograms); the existing proposal: procedure Pro is new Gen_Pro with Inline => True; package Pack is new Gen_Pack with Pure => True; (2) Always before the is (like packages); the new proposal (I think): procedure Pro with Inline => True is new Gen_Pro; package Pack with Pure => True is new Gen_Pack; (3) Always the same as the associated non-generic entity: procedure Pro is new Gen_Pro with Inline => True; package Pack with Pure => True is new Gen_Pack; (1) is inconsistent with packages; (2) is inconsistent with subprograms; and (3) is inconsistent between types of instantations. This doesn't seem particularly good no matter what we choose. I do think package instantiations are more common than subprogram instantations, so that argues for using (2) or (3). I think I slightly lean toward (3), but none of them is clearly better than the others. **************************************************************** From: Tucker Taft Sent: Monday, November 15, 2010 4:46 PM I think I still prefer choice (1), that is, the current AI wording. Putting more stuff into the middle of an instantiation seems unwieldy. **************************************************************** From: Robert Dewar Sent: Monday, November 15, 2010 5:28 PM I agree with this, and plan to change the GNAT implementation to conform with this thinking. **************************************************************** From: Brad Moore Sent: Monday, November 15, 2010 7:27 PM > (1) is inconsistent with packages; (2) is inconsistent with > subprograms; and > (3) is inconsistent between types of instantations. This doesn't seem > particularly good no matter what we choose. > > I do think package instantiations are more common than subprogram > instantations, so that argues for using (2) or (3). I think I slightly > lean toward (3), but none of them is clearly better than the others. Actually, there is one other set of possibilities which so far has not been discussed, (to the best of my knowledge). This again comes as two separate somewhat independent suggestions. 1) To just fix the package declaration case, move the aspect to immediately before the semi-colon. eg. package Ada is end Ada with Pure; For a larger package declaration the aspect comes long after where the pragma would typically appear. However, this might be something we get used to, perhaps a small price to pay for having a more consistent syntax. I suspect for smaller, simpler package specs, this form would generally be preferable to using pragmas. For larger packages, it may be a style preference, but there's nothing saying you can't still use pragmas, if you think that makes better sense. Since I had my eyebrows singed from yesterdays email :-) , I might as well continue with my other suggestion, which you can probably already guess. 2) That is, we could say that *all* aspect syntax always comes immediately before the semi-colon. This would make for a very simple rule for people to remember. It only impacts task type and protected type declarations (and package declarations), as those are the only syntax forms where aspect clauses come before the "is". Again, it might take a bit of getting used to, but might be worthwhile if the benefits outweigh the costs. **************************************************************** From: Robert Dewar Sent: Monday, November 15, 2010 7:57 PM > eg. > package Ada is > end Ada with Pure; I *very* strongly dislike this, you really want to see the Pure or Preelaborate at the start of the package and not at the end of the private part. This is why we require the pragmas to be at the start after all. > I suspect for smaller, simpler package specs, this form would > generally be preferable to using pragmas. For larger packages, it may > be a style preference, but there's nothing saying you can't still use > pragmas, if you think that makes better sense. You are saying "we did a bad job of designing placement of attributes so in a large package [almost any package is large enough as far as I am concerned] you won't be happy using the lousily designed aspect syntax. Never mind, we were forced to keep the pragmas for compatibility reasons, so you can still use those. > Since I had my eyebrows singed from yesterdays email :-) , I might as > well continue with my other suggestion, which you can probably already > guess. > > 2) That is, we could say that *all* aspect syntax always comes > immediately before the semi-colon. > > This would make for a very simple rule for people to remember. > > It only impacts task type and protected type declarations (and package > declarations), as those are the only syntax forms where aspect clauses > come before the "is". > > Again, it might take a bit of getting used to, but might be worthwhile > if the benefits outweigh the costs. Again, simply horrible, this is consistency gone mad! At this stage, I am strongly in favor of maintaining the status quo as written up. The suggestions for changing it seem to be opening up a can of worms (aka horrible suggestions for changing things). **************************************************************** From: Randy Brukardt Sent: Monday, November 15, 2010 8:05 PM ... > This again comes as two separate somewhat independent suggestions. > > 1) To just fix the package declaration case, move the aspect to > immediately before the semi-colon. > > eg. > package Ada is > end Ada with Pure; > > For a larger package declaration the aspect comes long after where the > pragma would typically appear. > However, this might be something we get used to, perhaps a small price > to pay for having a more consistent syntax. It's not about "getting used to it". It's about adding a whole lot of implementation difficulty. "Pragma Pure" is implemented by setting a compiler flag or state, and then checking each declaration as it appears whether it meets the requirements of that flag/state. That cannot be done if the aspect is at the end. The same holds anytime the aspect can affect the legality of the contents; that is, anytime there are significant independent declarations inside of the entity. Which is the program unit cases that you don't like. If we were to move the aspects to the end, then we'd have to drop the idea of converting program-unit pragmas into aspects, and quite possibly also have to drop and heavily modify various other aspects. (Effectively, we couldn't require any program unit aspects other than executable ones, because they wouldn't be implementable.) Honestly, you had a better argument when you suggested moving everything in front of the "is". That's only really ugly for types (subprograms usually don't have an "is" when they'd also have aspects). But since types are likely to be common I think readability and implementability trumps consistency here. The only sane alternative would be to drop the aspect syntax altogether from units, which *still* would be inconsistent, and we'd be losing a number of capabilities (most of the ones I care about, apart from the contracts stuff). **************************************************************** From: Randy Brukardt Sent: Monday, November 15, 2010 8:07 PM ... > At this stage, I am strongly in favor of maintaining the status quo as > written up. The suggestions for changing it seem to be opening up a > can of worms (aka horrible suggestions for changing things). Yup. The more we look at alternatives, the more it looks like we got it right the second time (the first time it was more like Brad's suggestion(s), which doesn't work very well.) **************************************************************** From: Robert Dewar Sent: Monday, November 15, 2010 8:13 PM > It's not about "getting used to it". It's about adding a whole lot of > implementation difficulty. "Pragma Pure" is implemented by setting a > compiler flag or state, and then checking each declaration as it > appears whether it meets the requirements of that flag/state. That > cannot be done if the aspect is at the end. And even if we fiddle in the compiler (e.g. by looking ahead and parsing the aspects first, which is actually likely to be pretty trivial in most compilers, probably Randy's compiler is an exception), the point is that the same thing that makes this awkward for the compiler makes things awkward for a reader. Basically a reader (or a one pass compiler) wants to know things at the appropriate point, and you definitely want to know that a package is pure as you read it. > If we were to move the aspects to the end, then we'd have to drop the > idea of converting program-unit pragmas into aspects, and quite > possibly also have to drop and heavily modify various other aspects. > (Effectively, we couldn't require any program unit aspects other than > executable ones, because they wouldn't be implementable.) Saying they are not implementable is much too strong, what Randy means is "I would have a hard time implementing them in my compiler", it actually would be trivial in GNAT, since as is more typical of Ada compilers, it builds a parse tree, then starts the semantic analysis. To me the stronger argument is difficulty for the reader, and in that sense, Randy's one pass compiler is a useful test, if he has trouble, then so will a reader of the code! > Honestly, you had a better argument when you suggested moving > everything in front of the "is". That's only really ugly for types > (subprograms usually don't have an "is" when they'd also have > aspects). But since types are likely to be common > > I think readability and implementability trumps consistency here. The > only sane alternative would be to drop the aspect syntax altogether > from units, which *still* would be inconsistent, and we'd be losing a > number of capabilities (most of the ones I care about, apart from the > contracts stuff). So Randy, are you comfortable signing up for the status quo? Sounds like it, and that's what Tuck prefers. Really I see only Brad at this stage suggesting any other action. **************************************************************** From: Brad Moore Sent: Monday, November 15, 2010 10:16 PM > So Randy, are you comfortable signing up for the status quo? Sounds > like it, and that's what Tuck prefers. Really I see only Brad at this > stage suggesting any other action. I see aspect specifications as an important new feature of the language. At the end of the day, I'd like to be able to say that we got it right. Knowing that we've considered all the possibilities will go a long way towards feeling comfortable with whatever decision we make. (Surely we've covered all the possibilities ...) It's too bad that there isn't one solution that fits perfectly, but I can be happy with the status quo. Arguing now for the status quo, I would say that if people get mixed up and try to put aspects in the wrong place, then I would think it should be easy enough for the compiler to give a clear error message hopefully that will tell the programmer where the aspect needs to be placed. I think people will quickly get the hang of it.... **************************************************************** From: Bob Duff Sent: Monday, November 15, 2010 8:17 PM > > eg. > > package Ada is > > end Ada with Pure; > > I *very* strongly dislike this, you really want to see the Pure or > Preelaborate at the start of the package and not at the end of the > private part. This is why we require the pragmas to be at the start > after all. Which is why I'm pretty happy with the pragmas. Yeah, I get that this new-fangled aspect thing is wonderful, but I'm nervous about how much trouble we're willing to go to... The main advantage of aspect clauses is that you don't have to name the thing. Saying "Foo is an inlined function." is fundamentally simpler than "Foo is a function. Foo is inlined." because in the latter case, the reader has to match up the two occurrences of "Foo". (The former is English for the aspect syntax; the latter for pragma syntax.) But Pure doesn't have that problem -- you can just say "pragma Pure;" and it refers to "this package". So I don't see why we want to go to a whole lot of trouble to make "Pure" into an aspect. Especially since I got "volunteered" to write up the wording that causes everything under the sun to be an "aspect". **************************************************************** From: Robert Dewar Sent: Tuesday, November 16, 2010 5:49 AM > But Pure doesn't have that problem -- you can just say "pragma Pure;" > and it refers to "this package". > So I don't see why we want to go to a whole lot of trouble to make > "Pure" into an aspect. I like the aspect notation for Pure, and I don't see it as a big deal, Certainly the implementation is trivial (and for GNAT, already done), and the description is done, so I am not sure what the "whole lot of trouble" you are talking about might be. > Especially since I got "volunteered" to write up the wording that > causes everything under the sun to be an "aspect". But that part of it is done :-) **************************************************************** From: Bob Duff Sent: Tuesday, November 16, 2010 6:57 AM It's not done. It's on my to-do list. **************************************************************** From: Robert Dewar Sent: Tuesday, November 16, 2010 7:01 AM But the syntax is done, right, which is the issue here. **************************************************************** From: Robert Dewar Sent: Tuesday, November 16, 2010 5:51 AM > Arguing now for the status quo, I would say that if people get mixed > up and try to put aspects in the wrong place, then I would think it > should be easy enough for the compiler to give a clear error message > hopefully that will tell the programmer where the aspect needs to be > placed. Indeed, not hard to do at all. **************************************************************** From: Robert Dewar Sent: Tuesday, November 16, 2010 7:06 AM Note that it is the syntax that is important to decide on and get into the RM. To me it doesn't matter so much whether the ARG decides to allow or disallow e.g. the Pure aspect, since once the syntax is OK, then implementations can implement any aspects they want. Which is why I would still like to see the *syntax* allow aspects on renamings, even if there are no officially allowed aspects. After all we allow a pragma Inline to apply to a renaming, so it seems quite arbitrary to say pragma Inline can be replaced with an Inline aspect, except for renamings, where only the pragma is allowed, and the aspect is illegal. **************************************************************** From: Robert Dewar Sent: Tuesday, November 16, 2010 8:45 AM > But the syntax is done, right, which is the issue here. Yes, there is a propoosed syntax, although it's still being discussed. At this point, I tend to agree with you and Tucker that the current propoosed syntax is the best we're going to get. Whether or not Pure is an aspect is still open -- no proposal one way or 'tother. I don't see much point in it, but maybe it's just for uniformity, which I can't tell without looking at the whole list of potential aspects. **************************************************************** From: Robert Dewar Sent: Tuesday, November 16, 2010 10:04 AM >> But the syntax is done, right, which is the issue here. > > Yes, there is a propoosed syntax, although it's still being discussed. > At this point, I tend to agree with you and Tucker that the current > propoosed syntax is the best we're going to get. And Brad seems to agree too :-) So let's just decide to stick with this syntax. > Whether or not Pure is an aspect is still open -- no proposal one way > or 'tother. I don't see much point in it, but maybe it's just for > uniformity, which I can't tell without looking at the whole list of > potential aspects. Well as I say, it's not critical what the resolution is. I am in favor of including this aspect, since I like the idea of not relying on pragmas for this kind of important semantic stuff. **************************************************************** From: Robert Dewar Sent: Tuesday, November 16, 2010 10:06 AM > Arguing now for the status quo, I would say that if people get mixed > up and try to put aspects in the wrong place, then I would think it > should be easy enough for the compiler to give a clear error message > hopefully that will tell the programmer where the aspect needs to be > placed How about > 1. pragma Ada_2012; > 2. package AspectInst is > 3. generic package P with -- OK > 4. Pure > 5. is > 6. end; > 7. > 8. generic package P2 is -- ERROR > | > >>> info: aspect specifications belong here > > 9. end with > | > >>> misplaced aspects for package declaration > > 10. Pure; > 11. > 12. package PP is new P with -- OK > 13. Pure; > 14. > 15. package PQ with -- ERROR > | > >>> misplaced aspects for package instantiation > > 16. Pure > 17. is new P; > | > >>> info: aspect specifications belong here > > 18. end; **************************************************************** From: Randy Brukardt Sent: Thursday, November 18, 2010 12:40 AM ... > Note that it is the syntax that is important to decide on and get into > the RM. The syntax *is* in the RM already, just look at draft 10 or later. :-) http://www.ada-auth.org/standards/ada12.html Of course, everything in the draft RM is subject to change. But I've only put things into it that I think are pretty stable (don't want to redo work). **************************************************************** From: Robert Dewar Sent: Thursday, November 18, 2010 6:29 AM ... > The syntax *is* in the RM already, just look at draft 10 or later. :-) Well, not really, because the only "RM" for Ada is the Ada 2005 standard. Yes, there is a draft RM, and of course I am perfectly aware of what it says now (that's why I refer to the status quo :-)) > http://www.ada-auth.org/standards/ada12.html > > Of course, everything in the draft RM is subject to change. But I've > only put things into it that I think are pretty stable (don't want to redo > work). Well sure, but the discussion of this particular aspect of aspects is still quite active, so your judgment of it as "pretty stable" is open to question. I am simply supporting your view that this should be regarded as a pretty stable feature, not subject to "redoing work" :-) **************************************************************** From: Tucker Taft Sent: Tuesday, November 16, 2010 8:23 AM [Editor's note: This was split off of a thread that is in AI05-0235-1.] > BTW, it seems that we really want formal by-reference parameters to be > a new object that happens to share memory with the old object. Besides > this accessibility rule (where claiming that dynamic accessibility is > a view property is unappealing), we also had similar issues with the > values of representation aspects like 'Size and 'Alignment. We surely > don't want to have to pass those along with parameters just so we can > report them accurately. (I recall we decided that wasn't necessary > with some phony > hand-waving.) I wouldn't be surprised if this keeps coming up until we > finally give in and change the definition... Perhaps, but there are several cases where things like Alignment, Size, accessibility level, constantness, vary according to the view. Note that a dereference of an access value gives a view of the designated object. If there are several different (general) access values of different types that designate the same object, the views they give could vary quite dramatically, but clearly there is only one object. **************************************************************** From: Randy Brukardt Sent: Tuesday, November 16, 2010 3:43 PM That seems to make a major muddle out of the entire idea of aspects. Either they have a well-defined model (that they belong to the entity, not the view), or we have to create a new model (that I do not understand at all), or they are just anything that Tucker wants (which is not the way to define a programming language!). In the first case, either Tucker is wrong here, or these things are just not aspects (because they don't meet the model of aspects). Neither of these match up with the existing language, so we have to reject this. But that means we have no model of aspects other than type aspects. We supposedly allow aspects for other than types to vary by view, yet there is nothing explaining how that works. We don't even know what constitutes different views. (Arguably, we could apply the ASIS definition of views that makes every usage name a different view - thus there are no requirements at all on such aspects). That effectively means that anything depending on aspects of entities other than types is implementation-defined. Perhaps that is OK for representation aspects (although I doubt it - it means that all of the ACATS tests on such aspects should be withdrawn, because they are testing things that are not requirements). It also means that all of the justification that I have made to Robert and others about the design of aspect clauses is bullshit. The truth is that they ought to be allowed on renames and anything else that creates a view; since they can be different for views at least in some cases, I don't see any reason to arbitrarily prevent that. When I asked this question about parameter passing, I was told that I was wrong and that no definition is needed. Maybe that is OK for representation aspects (although I strongly disagree), but it is not acceptable for any other aspect. Meaning that Bob will have to make sure that *every* aspect as wording describing how it works for views. That seems like a nightmare to me. What I would prefer is that the language was very clear that aspects are per-entity, not per-view, except perhaps in a set of specifically defined cases. So if you want parameters and dereferences to be able to give the "wrong" answer for object aspects, there should be explicit text allowing those exceptions. If we don't have some sort of rule like this, then we have descended completely into anarchy. And effectively, all aspects are completely implementation-defined, because there is no requirement ever that they have a particular value. That's madness. **************************************************************** From: Edmond Schonberg Sent: Tuesday, November 16, 2010 3:53 PM > What I would prefer is that the language was very clear that aspects > are per-entity, not per-view, except perhaps in a set of specifically > defined cases. So if you want parameters and dereferences to be able > to give the "wrong" answer for object aspects, there should be > explicit text allowing those exceptions. I fully agree with Randy. Aspects are per-entity, not per-view. I don't see the usefulness of "allowing" some aspects to depend on the view. Tuck's example that the alignment of a designated object might depend on the dereference that produces it can't possibly hold: how do you generate code for this? **************************************************************** From: Bob Duff Sent: Tuesday, November 16, 2010 4:27 PM Well, GNAT seems to manage. ;-) % cat align.adb cat align.adb with Text_IO; use Text_IO; procedure Align is procedure P (X : String) is begin Put_Line (X'Alignment'Img); end P; S : String := "Hello, world."; for S'Alignment use 2**8; begin Put_Line (S'Alignment'Img); P(S); end Align; % gnatmake -f align.adb gnatmake -f align.adb gcc -c align.adb gnatbind -x align.ali gnatlink align.ali % ./align ./align 256 1 % I didn't look at the generated code, but I'd guess it's just "move 256 into EAX" and "move 1 into EAX" (or whatever). Note that it's implementation defined whether or not X is a view of S! **************************************************************** From: Tucker Taft Sent: Tuesday, November 16, 2010 4:27 PM Here is an example: X : aliased Integer with Alignment => 1024; type Int_Ptr is access all Integer; Y : Int_Ptr := X'Access; pragma Assert(Y.all'Alignment = Integer'Alignment); pragma Assert(Y.all'Alignment /= X'Alignment); I don't see this as a big deal. The original discussion was about accessibility level, in any case. **************************************************************** From: Edmond Schonberg Sent: Tuesday, November 16, 2010 5:01 PM > Well, GNAT seems to manage. ;-) Not sure what this proves. Tuck's example involved two different access types with the same designated type. Here there is just an alignment clause, not two different contradictory aspects. This is the quote that worries Randy and me: Perhaps, but there are several cases where things like Alignment, Size, accessibility level, constantness, vary according to the view. Note that a dereference of an access value gives a view of the designated object. If there are several different (general) access values of different types that designate the same object, the views they give could vary quite dramatically, but clearly there is only one object. **************************************************************** From: Randy Brukardt Sent: Tuesday, November 16, 2010 5:13 PM ... > Perhaps, but there are several cases where things like Alignment, > Size, accessibility level, constantness, vary according to the view. > Note that a dereference of an access value gives a view of the > designated object. If there are several different > (general) access values of different types that designate the same > object, the views they give could vary quite dramatically, but clearly > there is only one object. Note that in this list, "constantness" is definitely not an aspect. We were originally discussing whether "accessibility level" works like an aspect, but there is no reason to assume it is one (which was my mistake). So neither of those really bear on the discussion. Size and Alignment surely are aspects. And we've discussed this before (in terms of parameters); we don't want to require the aspects to be required to be the same, because otherwise it would be necessary to pass them with all parameters just in case someone queried them. That would be silly. The problem is that the answer wasn't to explain when the aspects can depend on the view, but rather to say that they *always* depend on the view and then never say anything more. That means that you can *never* depend on an aspect other than a type aspect. That way lies madness. I should never have taken the "don't care" answer in the first place, but I could see that there would never be a strong definition for the case of representation aspects of objects. But now we have a much more general mechanism; we cannot leave it to individual implementers to do something useful - else we might as well not bother at all standardizing any of this beyond the syntax. (I get the feeling that Robert is in this camp.) **************************************************************** From: Bob Duff Sent: Tuesday, November 16, 2010 5:20 PM > Not sure what this proves. It proves that, as Tuck said, "things...vary according to the view". Whether that means the sky is falling, as Randy and Chicken Little might like to imply, I'm not so sure. ;-) >...This is the quote that worries Randy and me: Can you explain what the worry is? Is it a worry about RM wording, or something more substantial? I mean, X.all and Y.all can be the same object, yet the accessibility level depends on their (possibly different) access types. Should I worry about that? **************************************************************** From: Edmond Schonberg Sent: Tuesday, November 16, 2010 5:26 PM > The problem is that the answer wasn't to explain when the aspects can > depend on the view, but rather to say that they *always* depend on the > view and then never say anything more. That means that you can *never* > depend on an aspect other than a type aspect. Hopefully pre, post, and package aspects are equally trustworthy! we are just speaking about aspects of objects. **************************************************************** From: Randy Brukardt Sent: Tuesday, November 16, 2010 5:50 PM ... > > The problem is that the answer wasn't to explain when the aspects > > can depend on the view, but rather to say that they *always* depend > > on the view and then never say anything more. That means that you > > can *never* depend on an aspect other than a type aspect. > > Hopefully pre, post, and package aspects are equally trustworthy! we > are just speaking about aspects of objects. I would hope that they are trustworthy, but the current definition of aspects only has a special case defining that they are not view-dependent for types. (13.1(11/2)). There is no such rule for subprograms, objects, packages, or any other entities. That is what I'm concerned about. Bob Duff says: > It proves that, as Tuck said, "things...vary according to the view". > Whether that means the sky is falling, as Randy and Chicken Little > might like to imply, I'm not so sure. ;-) Being compared to Chicken Little, even with a smiley, is really nasty. My concern is simply that in the absense of some idea what an aspect is, particularly when views are involved, means that everything we've done so far is done without any clear idea of what we're doing. Everything I've done related to aspects has assumed that they are not view specific; if that premise is false, we need to revisit virtually every decision that has been made, because most of them depend heavily on that premise. (The obvious example is omitting aspect_clauses from renames.) Moreover, without a blanket rule defining how aspects work, every individual aspect has to provide that information. That means that aspects like Pre and Post need at least a sentence saying "This aspect is the same for every view of the associated subprogram." And aspects that are not like that need to explain what the rules are when views are involved. Otherwise, it is completely impossible to write an ACATS test or any other portable code using an aspect. The examples that both you and Tucker have shown that 'Alignment can be anything for an object, even when the value is specified for the object. There is no justification for the existing ACATS tests on object 'Alignment in that environment. As I've said, perhaps that is OK for representation aspects of objects (which are rather implementation-defined in any case), but that is simply not acceptable for something like Pre. If you think this is the "sky falling" as opposed to a real concern, then fine, but then we really have nothing to talk about. And I better brush up my Java skills, because I won't be doing Ada anymore. **************************************************************** From: Bob Duff Sent: Tuesday, November 16, 2010 6:35 PM > Being compared to Chicken Little, even with a smiley, is really nasty. I apologize! I really didn't mean it as a nasty insult -- just poking a little fun at you for what seemed to me like slightly over-the-top rhetoric (hence the smiley!). I am sorry. I do think you have a real, legitimate concern about the wording, and we can address it. **************************************************************** From: Tucker Taft Sent: Tuesday, November 16, 2010 10:19 PM I suspect Bob and I don't really understand the issue. Things like Size and Alignment have been part of Ada for a long time. Adding aspect specifications doesn't change much of anything about them, except for the syntax used to specify them. Objects are probably the only really special case, since they are clearly run-time entities, and we have many ways of referring to the same object. If you specify an aspect of an object, then at places where that aspect specification is visible and you are referring to the object via its declared name (as opposed to by some other name like a formal by-ref parameter or an access-value dereference), then an attribute reference corresponding to that aspect will presumably report the specified value. On the other hand, when referring to an object via a formal by-ref parameter, or via an access value dereference, then the attribute reference can end up returning a different value. It is presumably "conservative" for some appropriate definition of "conservative." That is, if you ask for the alignment of a formal parameter, it might in fact be more aligned. If you ask for the size, it might in fact have some extra padding at the end that nobody ever looks at. If you ask for the accessibility, it might in fact be longer-lived than it appears via the formal parameter. None of this is new with aspect specifications, so I am a bit surprised that there is any controversy and that this is a hot topic for discussion. It would probably help Bob and me if there were an example of an actual problem created by these long-standing characteristics of object representational aspects, or what makes this a bigger problem now that we have generalized aspect specifications. **************************************************************** From: Randy Brukardt Sent: Wednesday, November 17, 2010 9:24 PM I've covered this several times already (especially in my last message to Bob), but one more time: (1) You might have the above model in your head, but there is nothing in the Standard that codifies any of it. The standard really only defines aspects as entity-specific vs. view-specific for types. For all other kinds of entities, there is nothing much said about entity vs. view. (2) If we're going to generalize aspects as much as we are going to, we need to define these things carefully. For instance, your statement that "objects probably are the only special case" is not true vis-a-vis the standard wording. If we (for instance) want preconditions to be entity-specific rather than view specific, then we need wording to that effect somewhere. (3) Without some definition for other kinds of aspects (other than types), it is impossible to write any portable code (or any ACATS tests). That's because there is no definition for which views the specified value of an aspect has to be returned. The model you give above would be fine, but there is no normative justification for it in the Standard. (4) If indeed objects are the only special case, then the best way to do this is simply by saying so: "Unless otherwise specified, aspects are the same for all views of an entity." And then following that by an appropriate exception for objects: "For representation aspects of objects, views of an object for which the specification of an aspect are visible have the aspect as specified; other views may have an implementation-defined value of the aspect." Or something like that. (5) I don't view representation aspects of objects to be that big of a deal, as their values are implementation-defined anyway. Only ACATS tests really care about using them portably. But other kinds of aspects and aspects for other kinds of entities need to be dealt with. We surely do not want whether a package is Pure to depend on the view of the package, for example. (6) But note that I opened an AI (AI05-0083-1) specifically to address this question definitively for representation aspects of objects. I wanted the question answered then, but I only got a "ramification" that contains little real guidance (just some vaguely worded AARM notes). So I do not view this as a "new" issue, but rather one that has been festering for a long time. I only went along with the Ramification because of the implementation-defined nature of representation aspects means that not that much useful can be assumed about them anyway. But I still would much prefer real wording to explain when it is and is not allowed for the aspects to differ from those specified for an entity. (7) Finally, pretty much all of the decisions that we have made about syntax, rules, etc. about aspect_clauses have been made assuming that aspects are entity-specific rather than view-specific (surely in my case, and judging for Ed's reaction, I'm not the only one). Since that is wrong, I am no longer certain that we have gotten the right answers in all cases (the obvious example being whether to support the clauses on renames). I think it is important the we revisit all of the decisions with a new model in mind (even if that model is that aspects only differ for objects, we still need to think carefully about renames of objects). It's quite possible that not much needs to be changed, but I no longer have any confidence in my previous thinking on the topic. I hope this clarifies my position here. Perhaps I put my initial fears too strongly, but I cannot abide with leaving this all undefined, or assuming that the answers determined using an incorrect model of aspects are correct. ****************************************************************