comp.lang.ada
 help / color / mirror / Atom feed
* Predefined equality, reemergence
@ 2006-04-04 19:30 Adam Beneschan
  2006-04-04 19:46 ` Adam Beneschan
  0 siblings, 1 reply; 7+ messages in thread
From: Adam Beneschan @ 2006-04-04 19:30 UTC (permalink / raw)


Hi, everyone,

I'm having trouble understanding how the language rules about
predefined equality, specifically 4.5.2(24), behave when the component
type involved may be seen as "tagged" or "untagged" depending on
whether you're inside an instance.

Specifically, with regard to the program below: I would think that the
program would set Bool_1 to FALSE and Bool_2 to TRUE.  The way the
rules look to me, there's an implicit "=" declared in the generic for
Rec, and this "=" would be the predefined equality for Rec, which, when
matching components, uses the *predefined* (not the primitive) equals
for the matching component Comp1, since the formal type T is untagged.
The definition of Equal would use this version of "=".  Then, in the
instance, this implicit "=" is copied, and since Equal would use the
implicit "=", it should return FALSE when given two records whose
Comp1.Comp2 are different (5 and -5).  However, 12.3 says a whole new
set of primitive subprograms is implicitly declared for use outside the
instance, and it would differ since the type Rec in the instance
depends on the properties of the actual type Tagged_Rec, and I would
think that "="(Left,Right:Rec) is one of those primitive subprograms
that would differ; thus, outside the instance, "=" would refer to the
predefined equality that calls the *primitive* equals operator on the
component Comp1, since (outside the instance) the component type is
tagged, and thus the user-defined "=" would be called, which would
return TRUE if the absolute values of Comp2 are the same.

When compiled with the version of GNAT I'm using (which is not the
latest version), the program sets both Bool_1 and Bool_2 to TRUE, which
is not what I expected.

What's the correct output?  What's my mistake, if any, in interpreting
the rules?

Thanks for any help you can provide,

                      -- Adam


generic
    type T is private;
package Pak1 is
    type Rec is record
        Comp1 : T;
    end record;
    function Equal (Left, Right : Rec) return Boolean;
end Pak1;

package body Pak1 is
    function Equal (Left, Right : Rec) return Boolean is
    begin
        return Left = Right;
    end Equal;
end Pak1;


package Pak2 is
    type Tagged_Rec is tagged record
        Comp2 : Integer;
    end record;
    function "=" (Left, Right : Tagged_Rec) return Boolean;
end Pak2;

package body Pak2 is
    function "=" (Left, Right : Tagged_Rec) return Boolean is
    begin
        return abs (Left.Comp2) = abs (Right.Comp2);
    end "=";
end Pak2;


with Pak1;
with Pak2;
with Text_IO;
procedure Test69 is
    package New_Pak1 is new Pak1 (Pak2.Tagged_Rec);
    X : New_Pak1.Rec := (Comp1 => (Comp2 => 5));
    Y : New_Pak1.Rec := (Comp1 => (Comp2 => -5));
    Bool_1 : Boolean := New_Pak1.Equal (X, Y);
    Bool_2 : Boolean := New_Pak1."=" (X, Y);
begin
    Text_IO.Put_Line (Boolean'Image (Bool_1));
    Text_IO.Put_Line (Boolean'Image (Bool_2));    
end Test69;




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Predefined equality, reemergence
  2006-04-04 19:30 Predefined equality, reemergence Adam Beneschan
@ 2006-04-04 19:46 ` Adam Beneschan
  2006-04-04 23:00   ` Randy Brukardt
  0 siblings, 1 reply; 7+ messages in thread
From: Adam Beneschan @ 2006-04-04 19:46 UTC (permalink / raw)


I wrote:
> Hi, everyone,
>
> I'm having trouble understanding how the language rules about
> predefined equality, specifically 4.5.2(24), behave when the component
> type involved may be seen as "tagged" or "untagged" depending on
> whether you're inside an instance...........

I mistakenly posted this before thoroughly checking the AI's.  I found
that AI-123 appears to address this question.  I've been looking over
this AI and I still don't know the answer to my question.

                        -- Adam




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Predefined equality, reemergence
  2006-04-04 19:46 ` Adam Beneschan
@ 2006-04-04 23:00   ` Randy Brukardt
  2006-04-04 23:57     ` Adam Beneschan
  0 siblings, 1 reply; 7+ messages in thread
From: Randy Brukardt @ 2006-04-04 23:00 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> wrote in message
news:1144179981.495938.321410@e56g2000cwe.googlegroups.com...
> I wrote:
> > Hi, everyone,
> >
> > I'm having trouble understanding how the language rules about
> > predefined equality, specifically 4.5.2(24), behave when the component
> > type involved may be seen as "tagged" or "untagged" depending on
> > whether you're inside an instance...........
>
> I mistakenly posted this before thoroughly checking the AI's.  I found
> that AI-123 appears to address this question.  I've been looking over
> this AI and I still don't know the answer to my question.

I don't think AI-123 covers quite the same question. But let me take a quick
stab at it.

If in doubt, generics in Ada follow a substitution model; that is, the
result is the same if you wrote a non-generic equivalent. As such, I
certainly would not expect "=" (or anything else for that matter) to behave
differently depending on the location of the call. After all, you have a
*real* subprogram "=" (as opposed to an implicit one), and that subprogram
is going to have only one body of code.

Now, it might be interesting to find language rules to back up this
conclusion. :-) Personally, I find this as a case of Dewar's Rule (the
standard doesn't mean to say anything stupid, even if the actual words can
be read to come to a stupid conclusion). I'll leave finding wording as an
exercise for someone else...

                                       Randy.





^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Predefined equality, reemergence
  2006-04-04 23:00   ` Randy Brukardt
@ 2006-04-04 23:57     ` Adam Beneschan
  2006-04-05 12:16       ` christoph.grein
  0 siblings, 1 reply; 7+ messages in thread
From: Adam Beneschan @ 2006-04-04 23:57 UTC (permalink / raw)


Randy Brukardt wrote:
> "Adam Beneschan" <adam@irvine.com> wrote in message
> news:1144179981.495938.321410@e56g2000cwe.googlegroups.com...
> > I wrote:
> > > Hi, everyone,
> > >
> > > I'm having trouble understanding how the language rules about
> > > predefined equality, specifically 4.5.2(24), behave when the component
> > > type involved may be seen as "tagged" or "untagged" depending on
> > > whether you're inside an instance...........
> >
> > I mistakenly posted this before thoroughly checking the AI's.  I found
> > that AI-123 appears to address this question.  I've been looking over
> > this AI and I still don't know the answer to my question.
>
> I don't think AI-123 covers quite the same question.

Yeah, that one appears to apply only to language-defined types.

> But let me take a quick
> stab at it.
>
> If in doubt, generics in Ada follow a substitution model; that is, the
> result is the same if you wrote a non-generic equivalent. As such, I
> certainly would not expect "=" (or anything else for that matter) to behave
> differently depending on the location of the call. After all, you have a
> *real* subprogram "=" (as opposed to an implicit one), and that subprogram
> is going to have only one body of code.
>
> Now, it might be interesting to find language rules to back up this
> conclusion. :-) Personally, I find this as a case of Dewar's Rule (the
> standard doesn't mean to say anything stupid, even if the actual words can
> be read to come to a stupid conclusion). I'll leave finding wording as an
> exercise for someone else...

The reason I thought that "=" might mean something different in an
instance was because of the reemergence rules and how shared-code
generics (something that I know is a concern of yours) would be
difficult to implement without those rules.  For example,

    generic
        type INT is range <>;
    package Genpack is.....

Inside Genpack, anywhere you refer to "+" on objects of type INT, you
get the predefined addition operation even if "+" has been overridden
for the actual type.  Code sharing would be very difficult otherwise,
since you'd have to do an indirect call for every arithmetic
operation.

My first impression was that the same would apply to "=" on a generic
formal (untagged) private type---for shared-code generics, you'd want
the ability to compare two objects of your private type by doing a
straight bit comparison.  (Yeah, I know this causes problems for types
with holes in them.  So maybe this doesn't work anyway.)

Anyway, I did a little more digging, and found that the rule that
causes this reemergence is 12.5(8), which says, "In an instance, the
copy of such an implicit declaration declares a view of the predefined
operator of the actual type, even if this operator has been overridden
for the actual type".  This actually leads to some probably unintended
results if you compare objects of type T in the instance.  The rule
says that saying Left=Right in the instance, if both objects have type
T, means using the predefined equals operator, which is defined in
4.5.2.  Reading this section closely, it appears that if the actual
type for T is ACT, and ACT is a tagged record type, and there is a
user-defined primitive operator "=" on ACT, then: if ACT is a private
type, the predefined "=" is the user-defined "=" (4.5.2(15)), but if
ACT is not a private type, the user-defined "=" isn't used, and
instead we do a component-by-component equality operator as defined in
4.5.2(22-24).  Thus, you get *neither* the user-defined "=" *nor* the
straight bit comparison.  Is this really what was intended?  Should an
exception be made in 12.5(8) for "=" on generic formal private types?
Or at least when the actual type is tagged?

Finding this wording still doesn't strictly answer my question.
12.5(8) tells us what "=" means on objects of type T in an instance,
because it refers to an implicit declaration that gets copied.  But it
doesn't quite tell us what "=" means on a record that contains objects
of type T (i.e. Rec in my example)---I don't think 4.5.2 gives a clear
answer on this.  If "=" on objects of type T may mean something
different inside an instance than it does on objects of the actual
type outside the instance, then which "=" should be used to compare
components of type T, when we use "=" on objects of type Rec inside
the instance---and when we use "=" on objects of type Rec outside the
instance?

                                -- Adam




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Predefined equality, reemergence
  2006-04-04 23:57     ` Adam Beneschan
@ 2006-04-05 12:16       ` christoph.grein
  2006-04-05 18:47         ` Adam Beneschan
  0 siblings, 1 reply; 7+ messages in thread
From: christoph.grein @ 2006-04-05 12:16 UTC (permalink / raw)


Adam wrote:
"Reading this section closely, it appears that if the actual
type for T is ACT, and ACT is a tagged record type, and there is a
user-defined primitive operator "=" on ACT, then: if ACT is a private
type, the predefined "=" is the user-defined "=" (4.5.2(15)), but if
ACT is not a private type, the user-defined "=" isn't used"

I think you misread this sentence. It says: For a private type, it
depends on whether the full type is tagged or not.
If it is tagged, the primitive equality is used, else the predefined
equality is used.

So the result is: For tagged types (whether visibly tagged or not),
predefined equality when overridden is lost forever.

For other types, it re-emerges under certain circumstances.

(See
http://www.christ-usch-grein.homepage.t-online.de/AdaMagica/Dead.html)




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Predefined equality, reemergence
  2006-04-05 12:16       ` christoph.grein
@ 2006-04-05 18:47         ` Adam Beneschan
  2006-04-05 22:01           ` Robert A Duff
  0 siblings, 1 reply; 7+ messages in thread
From: Adam Beneschan @ 2006-04-05 18:47 UTC (permalink / raw)


christoph.grein@eurocopter.com wrote:
> Adam wrote:
> "Reading this section closely, it appears that if the actual
> type for T is ACT, and ACT is a tagged record type, and there is a
> user-defined primitive operator "=" on ACT, then: if ACT is a private
> type, the predefined "=" is the user-defined "=" (4.5.2(15)), but if
> ACT is not a private type, the user-defined "=" isn't used"
>
> I think you misread this sentence. It says: For a private type, it
> depends on whether the full type is tagged or not.
> If it is tagged, the primitive equality is used, else the predefined
> equality is used.
>
> So the result is: For tagged types (whether visibly tagged or not),
> predefined equality when overridden is lost forever.

I don't get how this result follows from the sentence in 4.5.2(15).
That sentence appears to talk about private types, but appears to say
nothing at all about non-private types.  In my example, 12.5(8) tells
us we need to find out what predefined equality is for the actual type,
and since the actual type isn't a private type, 4.5.2(15) would appear
not to apply at all.  Or is your last statement still speaking only
about private types?

Anyway, I can understand your statement that when an overriding "=" is
provided for a tagged type, the predefined "=" may no longer reemerge.
It just appears to me that there's an unintended loophole in the
language that makes this statement false in some instances---12.5(8)
says that "=" on a generic formal type refers to the predefined equals
operator on the actual, and there's nothing that says that the
predefined "=" on a tagged type T *is* *always* the overriding "="
operator if there is one.  4.5.2(24) says this is the case for a
*component* of type T, when you're using "=" on a larger object that
contains such a component; but it doesn't say that it's the case when
you're comparing objects of type T that are not components.

I'm prepared to accept that this is just an omission in the RM, and
that the predefined "=" never reemerges for tagged types.  That would
satisfy me; it answers my original question and convinces me that the
output of my example should be TRUE in both cases.  It still seems to
me that the RM is a bit vague on the question of what 12.3(16) and
8.3(13) say about the *body* of the implicit "=" on Rec (in my example)
that gets copied when instantiating.

                           -- Adam




^ permalink raw reply	[flat|nested] 7+ messages in thread

* Re: Predefined equality, reemergence
  2006-04-05 18:47         ` Adam Beneschan
@ 2006-04-05 22:01           ` Robert A Duff
  0 siblings, 0 replies; 7+ messages in thread
From: Robert A Duff @ 2006-04-05 22:01 UTC (permalink / raw)


"Adam Beneschan" <adam@irvine.com> writes:

> christoph.grein@eurocopter.com wrote:
> > So the result is: For tagged types (whether visibly tagged or not),
> > predefined equality when overridden is lost forever.

That's correct.

> Anyway, I can understand your statement that when an overriding "=" is
> provided for a tagged type, the predefined "=" may no longer reemerge.

I'm too lazy to dig in the RM right now, but I think what you're missing
is that the predefined "=" for a tagged type is _defined_ to do the
user-defined thing.  So you shouldn't talk about the predefined "="
reemerging, when you mean something like the bit-wise operator
reemerging.

And I believe the rules are written so that it doesn't matter whether
the type is _visibly_ tagged.  An untagged private type whose full type
is tagged has properly-composing "=".  And generics are like
"inside-out" packages, so a generic formal untagged type has
properly-composing "=" if the actual type is tagged.

> I'm prepared to accept that this is just an omission in the RM, ...

I don't think the RM gets this wrong, but of course I could be
mistaken.

>...and
> that the predefined "=" never reemerges for tagged types.

Again, you mean the bit-wise operator.

>...  That would
> satisfy me; it answers my original question and convinces me that the
> output of my example should be TRUE in both cases.

I believe it should be TRUE in both.

By the way "bit-wise" isn't quite right, either, since minus-zero and
plus-zero are supposed to be equal for floating point types with signed
zeros.

- Bob



^ permalink raw reply	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2006-04-05 22:01 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2006-04-04 19:30 Predefined equality, reemergence Adam Beneschan
2006-04-04 19:46 ` Adam Beneschan
2006-04-04 23:00   ` Randy Brukardt
2006-04-04 23:57     ` Adam Beneschan
2006-04-05 12:16       ` christoph.grein
2006-04-05 18:47         ` Adam Beneschan
2006-04-05 22:01           ` Robert A Duff

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox