[net.lang.ada] The equals function.

RRACINE@ADA20.ISI.EDU (Roger Racine) (09/25/86)

The problem, according to Pat Rogers is:
<Dear Ada language-lawyers,
<
<Here's a question:
[I deleted a discussion of a possible recursion problem that he 
wants to avoid]
<Now the question: suppose that LP is actually an access type, rather than 
<derived from Integer. So,
<
<
<    package P is
<
<      type LP is limited private;
<
<      function "="( Left, Right : LP ) return Boolean;
<
<    private
<
<      type LP is access Integer;  -- or access whatever
<
<    end P;
<
<
<In the body, the above approach cannot be used, since there is no 
<conversion or qualification type available. To wit,
<
<    package body P is
<
<      function "="( Left, Right : LP ) return Boolean is
<      begin
<    	if Left = null then ...
<
<This is a recursive call to P."=" on my compiler (yes, validated).
<
<
<
<One could simply do the following (my current approach), 
<
<    begin
<      return Left.all = Right.all;  -- null pointer dereference possible
<    exception
<      when Constraint_Error =>  
<        return False;
<    end "=";
<
<However, in some situations it may be desirable to check for the null
<value rather than relying on Constraint_Error (which might be suppressed later
<by another programmer, etc... ). Maybe it is just correct in some particular
<application to have two objects of type LP be equal if they are both null. 
<
<In those cases, what can be done ?
<
<Is the compiler correct ?   I've not had time to check it on some others.
<
<Any suggestions will be appreciated.
<
<Thanks !
<

This actually is a more interesting problem than I thought at first.
People tend to like the "infix" notation for operators. They never think
about using the fully qualified name. Therefore, I thought that all that
was needed was:

      if STANDARD."="(LEFT, null) then

Unfortunately, the equality operator is not found in package STANDARD!
Appendix C of the reference manual states:
     This annex outlines the specification of the package STANDARD
     containing all predefined identifiers in the language.
This seems to say that the equality operator should be there. But it is not
there.

Section 8.6 states:
     The predefined types (for example the types BOOLEAN, CHARACTER
     and INTEGER) are the types that are declared in a predefined
     package called STANDARD; this package also includes the 
     declarations of their predefined operations. The package STANDARD
     is described in Annex C. Apart from the predefined numeric types,
     the specification of the package STANDARD must be the same for all
     implementations of the language.

Since an access type (and array types and record types) are not predefined
types (as opposed to INTEGER, et al), this would seem to allow for those
equality operators to be missing. In fact, since the specification "must
be the same" as the Annex C spec., they would seem to be required to be 
missing. WHERE ARE THEY DECLARED?

I checked with two validated compilers, and both rejected the STANDARD."="
approach.

Roger Racine
C.S. Draper Lab.
-------

BBardin@ADA20.ISI.EDU (09/29/86)

In response to your question "Where are the predefined operations for
array, access and record types defined if not in package 'Standard':

I think the answer follows from the realization that the predefined
types 'Integer', 'Characer' and 'Boolean' are quite different things
than array, record and access types.  The later are classes (or types)
of types, while the former are instances of Ada type classes.
i.e., The predefined type 'Integer' is just one instance of all possible
integer types, while 'Boolean' and 'Character' are predefined 
enumeration types (enumeration being the class).   

ARM 3.3.3(2) states that the predefined operations for a type (not a
type class) occur after the type declaration (an instance of the
class).  The predefined operations for 'Integer', 'Character' and
'Boolean' are found in 'Standard' because that is where the type
declarations for these types are found.  There are no predefined
operations for 'array', 'record', and 'access' qua type classes, only
for actual array, record and access types.

Note that 'String' is a predefined array type, (just as 'Integer' is a
predefined integer type) and the predefined operations for 'String'
are found immediately following the declaration in package 'Standard'.
Note also that the term 'integer' has been overloaded to refer to both
a class of types (as in "... 'Short_Integer' is an integer type ...")
and a specific instance of a type (as in "... the predefined type
'Integer' ...").

I hope this has been of some help,

John Prentice,
GMHEC
-------

jankok@mcvax.uucp (Jan Kok) (09/30/86)

In article <8609252153.AA03089@ucbvax.Berkeley.EDU> RRACINE@ADA20.ISI.EDU (Roger Racine) writes:
>The problem, according to Pat Rogers is:
My summary: declaring an "=" operator for a limited private type which
            is actually 'access INTEGER' leads to a recursive call of this "=".
Roger answers correctly:
>                    all that was needed was:
>
>      if STANDARD."="(LEFT, null) then
>
My summary: qualify the operator (in prefix notation) instead of try to
            help the overloading resolution algorithm by qualifying the
            operands.
I ignore other helpful answers which avoid the interesting problem, like:
   Introduce a hidden type for the 'access INTEGER' type.

But then Roger adds:
>Unfortunately, the equality operator is not found in package STANDARD!

He quotes App. C and section 8.6 of the ARM to support this, and ends with

>I checked with two validated compilers, and both rejected the STANDARD."="
>approach.

That's the interesting part (to me).
I checked with a validated compiler (wellll, expired now), and it
recognizes STANDARD."=".
So the match is still open, but the problem should not be settled
by a democratic check on all validated compilers of course.

I tend to accept what the compiler I can use does, and my attempt of an
explanation is:
1. According to ARM 4.5.2, "=" is predefined.
2. App. C does not contain, and does not pretend to contain all
   specifications of predefined operators. It contains a lot of comments.
   The package STANDARD in App C contains, as it says it should:
      the type declarations for the predefined types, together with
      some subtypes and packages.
   It says that the predefined operators are IMPLICIT. This applies
   to operators for 'any type' like "=" as well as those for the predefined
   types.
3. The missing link is:
   Where does the manual say that STANDARD is the appropriate prefix
   for the full name of the implicit operators.
   I would say: if Roger's two validated compilers accept STANDARD."+",
   they should accept STANDARD."=" as a matter of consequence.

jankok@mcvax.uucp (Jan Kok) (09/30/86)

CORRECTION
I must apologize about my previous posting, the subject of the existence
of the operator STANDARD."=" has been too difficult for me. I maintain
that it is interesting, at least I learned something.

I wrote:
In article <310@zuring.mcvax.UUCP> jankok@zuring.UUCP (Jan Kok) :
>
>I checked with a validated compiler (wellll, expired now), and it
>recognizes STANDARD."=".

But my test was too simple. I checked whether it recognized STANDARD."="
for operands of a predefined type like FLOAT. It does.
But my compiler does not accept STANDARD."=" for operands of a
user-defined type like 'access INTEGER'.

With help of a colleague, I may offer a better explanation: for a new
type, the prefix in the expanded name should be that of the module
(package, etc.) containing the type declaration. So, there is no
disagreement among validated compilers about this issue, as far as
tests have been made now by net-readers.

The person with the original problem is not helped by this. The prefix
can be used if the new definition and the "=" used in the call are
(possibly implicitly) declared in different modules.
-- 
Mail: Jan Kok, CWI (afd. NW), Postbus 4079, NL-1009 AB Amsterdam, Nederland
UUCP: {seismo, decvax, philabs, okstate, garfield}!mcvax!zuring!jankok
---------------------------------------------------------------
   One of the Warner Bros to Albert Einstein:
      I have a theory about relatives myself : Don't hire them!