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

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

!standard A.18.2(87/2)          21-06-07 AI12-0434-1/03
!standard A.18.3(59/2)
!standard A.18.4(18/2)
!standard A.18.7(17/2)
!standard A.18.10(76/3)
!class binding interpretation 21-05-28
!status Amendment 1-2012 21-06-07
!status ARG Approved 14-0-0 21-06-03
!status work item 21-05-28
!status received 21-05-28
!priority Low
!difficulty Easy
!qualifier Clarification
!subject Equality operators for container cursors
!summary
The equality operator for a container cursor, like any other operator in a language-defined package, can be user defined.
!question
A.18.4 (18/2) says:
The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
Can this operation be user-defined? (Yes.)
!recommendation
(See Summary.)
!wording
Modify A.18.4 (18/2):
The {primitive}[predefined] "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
{AARM To Be Honest: "The primitive "=" operator" is the one with two parameters of type Cursor which returns Boolean. We're not talking about some other (hidden) primitive function named "=".}
Change A.18.2 (87/2), A.18.3 (59/2), A.18.7 (17/2), and A.18.10 (76/3) in the same way.
!discussion
The author believes that this is much ado about nothing. Nothing in the RM says that this operator has to be predefined. The use of "predefined" here is just identifying the operator being discussed. As-if implementations of language-defined packages are always allowed; in particular, any operator can be user-defined so long as that definition meets the requirements of the language (such as composition) and the redefinition does not change the semantics as visible to the user (so one has to be careful with parameter names and subtypes). No language-defined package would be implementable without such an interpretation - one always needs to add semantic dependencies for helper packages to implement the private parts of language-defined packages.
Taken literally, this interpretation would mean that no implementer could use a user-defined operator in a language-defined package unless that operator is explicitly defined in the specification of the package. That would mean that heroic efforts (such as building almost all language-defined packages into the compiler) would be needed for many Ada types. For instance, only predefined "=" could be used for type Controlled, meaning a special-case implementation would be needed for such equality.
Since the "=" operator for cursors is not explicitly present in the specification, "predefined" was used to identify the operator whose behavior was being specified. We still need some phrase to do that, as we are not intending to put any requirements on "=" other than the usual one.
Note that 4.5.2(32.1/1) requires composition of equality of this and all other private types in language-defined packages, and AARM A.18(5.q/2) specifically calls out composition as required for the containers and cursors. There's no need to mention that further.
---
We considered other possible changes here:
(1) Define an "=" operator for cursors in the specification of all of the container packages. Then the word "predefined" is not needed in the paragraph above. This was rejected as it makes the operator user-defined even when that is not necessary.
(2) Use the description of the "usual" equality as defined in 4.5.2(9.8/5):
"the primitive equality operator that is type conformant with that of the corresponding predefined equality operator"
Surprisingly, this was considered too wordy. :-)
(3) Leave it as it is, and add an AARM To Be Honest note (or perhaps Implementation Note) telling any implementer that the use of "predefined" in this paragraph simply identifies the operator being specified, and has no effect on how it could be implemented. This was rejected as being misleading.
!corrigendum A.18.2(87/2)
Replace the paragraph:
The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
by:
The primitive "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
!corrigendum A.18.3(59/2)
Replace the paragraph:
The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
by:
The primitive "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
!corrigendum A.18.4(18/2)
Replace the paragraph:
The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
by:
The primitive "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
!corrigendum A.18.7(17/2)
Replace the paragraph:
The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
by:
The primitive "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
!corrigendum A.18.10(76/3)
Replace the paragraph:
The predefined "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
by:
The primitive "=" operator for type Cursor returns True if both cursors are No_Element, or designate the same element in the same container.
!ASIS
No ASIS effect.
!ACATS test
No ACATS test needed.
!appendix

From WG 9 Review Issue #144.

A.18.4 (18/2) says:

   The predefined "=" operator for type Cursor returns True if both cursors
   are No_Element, or designate the same element in the same container.

In fact, it is fine if there is a user-defined "=" operator for type Cursor,
so long as it composes properly. Hence, I would suggest we drop the
"predefined" and either add an AARM note or an Implementation Requirement
that this "=" operator composes properly.

Same problem occurs in A.18.2 (87/2), A.18.3 (59/2), A.18.7 (17/2), and 
A.18.10 (76/3)

All five of these can be found by searching the RM for the exact phrase "if 
both cursors"

[Reply from Randy Brukardt:]

4.5.2(32.1/1) clearly applies to type Cursor (it is a nonlimited type declared 
in a language-defined package), so I don't think anything normative about 
composition is required (it is required of equality of all language-defined 
types). I won't even bother with an AARM note, since we discuss the fact that
language blanket rules apply to containers in the introduction (AARM
A.18(5.q/2) specifically calls out composition).

I personally think this request is overly pedantic; from the perspective of a 
user of a package, whether an operator is predefined or user-defined is 
irrelevant - whether something is privately overridden is neither visible nor
matters. I'd guess that there are quite a few similar wordings throughout the
RM. Moreover, this wording has been present since Ada 2005, and there's no 
evidence that anyone was confused.

Anyway, I'm rather close to clicking on the deferred label, but I'll leave 
this unmarked for now, if there is time before next Friday, I'll deal with it.

[Reply from Tucker Taft:]

This is not actually just "pedantic" since attempts to ensure that the 
"predefined" equality had the right properties significantly complicated the
implementation, and led to some bugs. Once we concluded that all that mattered
was that the equality operator composed, we were able to simplify things and
avoid various bugs. So I believe we should at a minimum remove "predefined"
from the normative wording. Whether we should also add an AARM note somewhere
is a separate issue, and I leave that in the Editor's hands...

[Reply from Randy Brukardt:]

I disagree - "as if" changes to language-defined packages are always allowed, 
and certainly redefining an operator falls into that category. If that wasn't
true, pretty much the entire set of Ada predefined units would require heroic
efforts to implement. Your always allowed to add things (declarations, context
clauses, etc) that don't change the user semantics of a unit. Nothing given in
English text changes that fact, so such a concern is pedantic at best. I think
there are dozens of similar cases in the RM, and I don't see any reason to
prioritize this one over any others (other than that someone is complaining).
Still, the absolute lowest priority to fix for me.

[Reply from the editor:]

I've made a mostly empty AI (AI12-0434-1) for this topic. I don't believe that
just dropping "predefined" works, as there is no equality visible in the
specification and it is unclear what is being talked about in this case (there
could be other equalities that are user-defined or hidden from users). I
suppose we could say "primitive" equality here, similar to the rules in 4.5.2,
which refers to the equality that is used for composition.

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

Questions? Ask the ACAA Technical Agent