Of what types is an attribute an operation? AI-00598/00 1 88-11-08 BI RE !standard 03.03.03 (07) 88-11-08 AI-00598/00 !class binding interpretation 88-11-08 !status received 88-11-08 !topic Of what types is an attribute an operation? !summary 88-11-08 !question 88-11-08 !recommendation 88-11-08 !discussion 88-11-08 !appendix 88-11-03 ***************************************************************************** !section 03.03.03 (07) Norman Cohen 88-11-03 83-01031 !version 1983 !topic Of what types is an attribute an operation? !references AI-00043 Paragraphs 1 through 7 of 3.3.3 read, in part: 1 The set of operations of a type includes the explicitly declared subprograms that have a parameter or result of the type.... 2 The remaining operations are each implicitly declared for a given type declaration, immediately after the type definition. These implicitly declared operations comprise the basic operations, the predefined operators (see 4.5), and enumeration literals.... The operations implicitly declared for a given type declaration occur after the type declaration and before the next explicit declaration, if any.... 3 A basic operation is an operation that is inherent in one of the following: ... 7 o A numeric literal (for a universal type), the literal null (for an access type), a string literal, an aggregate, or an attribute. Furthermore, paragraphs 1 and 3 of 4.1.4 read, in part: 1 An attribute denotes a basic operation of an entity given by a prefix. ... Of what types is an attribute an operation? AI-00598/00 2 88-11-08 BI RE 3 ... An attribute can be a basic operation delivering a value; alternatively, it can be a function, a type, or a range.... This suggests several questions: 1. Is every attribute a basic operation of some type? 2. Can an attribute be a basic operation of more than one type? 3. Of what types is a given attribute a basic operation? 4. When an attribute is renamed as a function or passed as a generic actual parameter, are the names declared by the renaming declaration or the generic parameter declaration considered to denote an entity that is an operation of the parameter type and of the result type? These questions are inspired by AI-00043. During consideration of AI-00043 it was natural to think of the attribute X'ADDRESS as a basic operation of type SYSTEM.ADDRESS, and the conclusion of AI-00043 is consistent with this view, but this view is not supported by the Standard. Here are some of the issues relevant to questions 1-4: 1. Is every attribute a basic operation of some type? It does not necessarily follow from 3.3.3 that every attribute is a basic operation. 3.3.3(3) can be read (in conjunction with 3.3.3(7)) as meaning that IF an operation is "inherent in" a given attribute, THEN that attribute is a basic operation, but that not all attributes necessarily have operations inherent in them. A strict reading of 4.1.4(1) suggests that an attribute is an operation of whatever entity is denoted by its prefix. However, since the Standard makes no other reference to operations of program units, operations of labels, operations of entries, or operations of objects, this paragraph should not be taken literally. The wording of 4.1.4(3) strongly and, it seems, intentionally suggests that only attributes delivering values are basic operations. An attribute yielding a function, a type, or a range is not. Thus the attributes P'BASE and P'RANGE are not operations. It would follow from this line of reasoning that the attributes P'IMAGE, P'POS, P'PRED, P'SUCC, P'VAL, and P'VALUE are not operations. It might be argued that the attributes P'IMAGE, P'POS, P'PRED, P'SUCC, P'VAL, and P'VALUE, while not themselves operations, are second-order "meta-operations," providing functions that are, in turn, operations. Consider, however, the verbs used to describe the meanings of the four kinds of attributes: Each attribute delivering a value "yields" that value. The attribute P'RANGE also "yields" a range (3.6.2(7), A(36)). The attribute P'BASE "denotes" a type according to A(4), while 3.3.3(9) simply reads, "The base type of T," eliding the verb. Of what types is an attribute an operation? AI-00598/00 3 88-11-08 BI RE According to 3.5.5, paragraphs 5 through 12, as well as Annex A, the attributes P'IMAGE, P'POS, P'PRED, P'SUCC, P'VAL, and P'VALUE do not "yield" functions; rather, each of these attributes "is" a function. Thus each of these attributes is an operation if and only if the corresponding function is an operation. It would be very strange if these functions were not operations. Except for P'VAL (described as a "special function" because its parameter can be of any integer type) and P'POS (which has returns a universal_integer result), these functions act much like functions defined by subprogram declarations. They can be renamed (8.5(9)) and passed as generic actual parameters (12.3.6(6), a note) and are considered for these purposes to have parameter and result type profiles. Indeed, 12.3(11) states, "For a name that denotes a generic formal subprogram: The corresponding name denotes the subprogram, enumeration literal, or entry named by the associated generic actual parameter (the actual subprogram)," and 12.3.6(1) states, "A formal subprogram is matched by an actual subprogram, enumeration literal, or entry...," suggesting that a functional attribute is simply a subprogram. (On the other hand, the semantics of subprogram calls given in 6.4(1) do not apply to attributes because attributes do not have function bodies.) 2. Can an attribute be a basic operation of more than one type? 3.3.2(2) states that all operations other than explicitly declared subprograms are "implicitly declared for a given type declaration, immediately after the type definition.... The operations implicitly declared for a given type declaration occur after the type declaration and before the next explicit declaration, if any." Thus an attribute (or any other basic operation) can only be declared "for" a single type declaration. Is an implicitly declared operation an operation "of" a given type (in the sense of 3.3.3(1)) if and only if it is declared "for" the declaration of that type (in the sense of 3.3.3(2))? If so, certain anomalies arise. For example, an explicitly declared subprogram procedure P (X1: in T1; X2: in T2); is an operation of both T1 and T2, but given the declaration type NT1 is new T1; the derived subprogram procedure P (X1: in NT1; X2: in T2); is an operation of NT1 but not of T2, since it is declared "for" the derived-type declaration. 3. Of what types is a given attribute a basic operation? Of what types is an attribute an operation? AI-00598/00 4 88-11-08 BI RE One possible answer is that an attribute is a basic operation only if its prefix denotes a subtype, in which case it is a basic operation of the corresponding base type. 4.1.4(1) can be read as supporting this view. Alternatively, we might also consider an attribute to be a basic operation if its prefix denotes a value, in which case it is a basic operation of the type of the value. Another possible answer, formed by analogy to explicitly declared subprograms, is that an attribute is an operation of a given type if it has a prefix of that type, if it has a parameter of that type, or if it yields a result of that type. (The dimension numbers in the array attributes are part of the attribute designators, not parameters, so the A'FIRST(2) attribute, for example, is distinct from the A'FIRST(1) attribute and is not an operation of type universal_integer.) While this view is intuitively appealing (and is probably the basis for thinking of the attribute A'ADDRESS as an operation of type SYSTEM.ADDRESS), it does not seem to be supported by the Standard. Indeed, such an interpretation would cause several attributes to be operations of type universal_integer but not of any other integer type, contradicting 4.10(2,3), which purports to contain a comprehensive description of the universal_integer operations. Perhaps the most convincing answer is that type of which each attribute is a basic operation can be inferred from the sections of the Standard listing the basic operations for each class of types: - T'BASE is listed as a basic operation of any discrete type T in 3.3.5(3), of any floating-point type T in 3.5.8(3), of any fixed-point type T in 3.5.10(3), of any array type in 3.6.2(11), of any record type in 3.7.4(4), of any access type in 3.8.2(4), and of any private type in 7.4.2(2). It is not listed as an attribute of a task type in 9.9, but 3.3.3(8) states (and A(4) suggests) that T'BASE is defined for every type or subtype T. - The attribute T'SIZE, where T denotes a type or subtype, is listed as a basic operation of any discrete type T in 3.5.5(3), of any floating-point type T in 3.5.8(3), of any fixed-point type T in 3.5.10(3), of any array type in 3.6.2(11), of any record type in 3.7.4(4), of any access type in 3.8.2(4), and of any private type in 7.4.2(2). It is listed in 9.9(4) as being "defined for" any task type, but 9.9 does not state that this attribute is a basic operation of a task type. - The attributes A'ADDRESS and A'SIZE, where A denotes an object, are listed as basic operations of the type of the object for discrete types in 3.5.5(14), for floating-point types in 3.5.8(14), for fixed-point types in 3.5.10(13), for array types in 3.6.2(11), for record types in 3.7.4(4), for access types in 3.8.2(4), and for private types in 7.4.2(2). These attributes are listed in 9.9(4) as being "defined for" values or objects of a task type, but 9.9 does not state that these attributes are basic operations of a task type. There is no basis for concluding that A'ADDRESS is an operation of type SYSTEM.ADDRESS (except in the Of what types is an attribute an operation? AI-00598/00 5 88-11-08 BI RE special case that A itself is of type SYSTEM.ADDRESS). - The attributes T'FIRST and T'LAST, where T is a scalar type, are listed as basic operations of any discrete type T in 3.5.5(3), of any floating-point type T in 3.5.8(3), and of any fixed-point type T in 3.5.10(3). - The attribute T'WIDTH is listed as a basic operation of any discrete type T in 3.5.5(3,4). - The functional attributes T'POS, T'VAL, T'SUCC, T'PRED, T'IMAGE, and T'VALUE are listed in 3.5.5(5..13) as basic operations of any discrete type T. There is no basis for concluding, for example, that T'POS and T'VAL are operations of universal_integer or any other integer type, or that T'IMAGE and T'VALUE are operations of type STRING, even though T'IMAGE can be renamed as a function with a STRING result and T'VALUE as a function with a STRING parameter. Thus, given the declaration type NS is new STRING; we presumably do not derive an overloaded attribute BOOLEAN'IMAGE with a result of type NS or an overloaded attribute BOOLEAN'VALUE with a parameter of type NS (even though the parent type, STRING, is declared in the same package, STANDARD, as the two attributes). - The attributes T'DIGITS, T'EPSILON, T'EMAX, T'SAFE_EMAX, T'MACHINE_RADIX, T'MACHINE_MANTISSA, T'MACHINE_EMAX, and T'MACHINE_EMIN are listed as basic operations of any floating-point type T in 3.5.8(4 .. 14). - The attributes T'DELTA, T'FORE, and T'AFT are listed as basic operations of any fixed-point type in 3.5.10(4,8,9). - The attributes T'MANTISSA, T'SMALL, T'LARGE, T'SAFE_SMALL, T'SAFE_LARGE, T'MACHINE_ROUNDS, and T'MACHINE_OVERFLOWS are listed as basic operations of any floating-point type T in 3.5.8(4..14) and of any fixed-point type T in 3.5.10(5..13). - The attributes A'FIRST(N), A'LAST(N), A'RANGE(N), and A'LENGTH(N), as well as their counterparts in which the dimension is left implicit, are listed in 3.6.2(2..10) as basic operations of any constrained array subtype A. Similar attributes in which A denotes a value are listed as basic operations of the type of A for array types in 3.6.2(2..10) and for access types designating array types in 3.8.2(2). Presumably, the operation "inherent in" an attribute whose prefix denotes an array subtype is the same as the operation "inherent in" an attribute whose prefix denotes an array value; otherwise the former would be an operation of a subtype but not an operation of the corresponding base type, a notion alien to Ada. There is no basis for concluding that A'FIRST(N) and A'LAST(N) are operations of the index type of A. Of what types is an attribute an operation? AI-00598/00 6 88-11-08 BI RE - The attribute T'CONSTRAINED is listed as a basic operation of any private type T in 7.4.2(8,9). - The attribute A'CONSTRAINED, where A denotes an object, is listed as a basic operation of the type of the object for record types with discriminants in 3.7.4(2,3) and for private types with discriminants in 7.4.2(2). - The attributes T'TERMINATED and T'CALLABLE, where T denotes a value, are listed as basic operations of the type of T for access types designating task types in 3.8.2(3). These attributes are listed in 9.9(1,3) as being "defined for" values or objects of a task type, but 9.9 does not state that these attributes are basic operations of that task type. - The attribute T'STORAGE_SIZE is listed as a basic operation of any access type in 3.8.2(4). It is listed in 9.9(4) as being "defined for" task types and task objects, but 9.9 does not state that this attribute is a basic operation of a task type. This analysis leaves several questions unanswered: - Is the attribute T'BASE defined (albeit useless) for a task type? - Was it intended that the attributes described in 9.9 as "defined for" a task object, task value, or task type (T'CALLABLE, T'TERMINATED, T'STORAGE_SIZE, T'SIZE, and T'ADDRESS) be basic operations of a task type? Is the attribute E'COUNT an operation of the task type to which entry E belongs? - When the prefix of an 'ADDRESS attribute denotes a program unit, label, or entry, is the attribute an operation of any type? - Are the attributes R.C'POSITION, R.C'FIRST_BIT, or R.C'LAST_BIT operations of any type? If so, they would presumably be operations of the type of record component R.C, and thus listed as basic operations for every class of types, but the Standard does not list them as basic operations for any class of types. 4. When an attribute is renamed as a function or passed as a generic actual parameter, are the names declared by the renaming declaration or the generic parameter declaration considered to denote an entity that is an operation of the parameter type and of the result type? Assume that T'IMAGE and T'VALUE are not considered operations of type STRING; otherwise, there is no issue. Given the declaration function MY_IMAGE (B: BOOLEAN) return STRING renames BOOLEAN'IMAGE; is MY_IMAGE an operation of type STRING? Similarly, given the generic package generic Of what types is an attribute an operation? AI-00598/00 7 88-11-08 BI RE with function MY_IMAGE (B: BOOLEAN) return STRING; package GP is ... end GP; and the instantiation package P is new GP (MY_IMAGE => BOOLEAN'IMAGE); does MY_IMAGE denote an operation of type STRING within the generic unit? The answer depends on the definition of an "explicitly declared subprogram." By 3.3.3(1), "The set of operations of a type includes the explicitly declared subprograms that have a parameter or result of the type...." A subprogram renaming declaration is an explicit declaration, but it probably cannot be said to declare the subprogram, since 8.5(1) states that a renaming declaration "declares another name for an entity," not that it (re)declares an entity. A generic parameter declaration is an explicit declaration, but by 12.1.3(1), the kind of generic parameter declaration considered here "declares a generic formal subprogram," not a subprogram. Thus, in neither case above is MY_IMAGE an explicitly declared subprogram. In fact, 8.5(3) indicates that the name declared by a renaming declaration "denotes" the renamed entity and 12.3(11) indicates that within a generic instance a generic formal function "denotes" the corresponding generic actual parameter. Thus, in each case, MY_IMAGE denotes the attribute BOOLEAN'IMAGE. Presumably, a given entity either is or is not an operation of a given type, regardless of which name we use to denote the entity.