comp.lang.ada
 help / color / mirror / Atom feed
* tagged primitive operation and freezing
@ 2010-11-13  3:24 troll
  2010-11-13 10:24 ` Ludovic Brenta
  0 siblings, 1 reply; 5+ messages in thread
From: troll @ 2010-11-13  3:24 UTC (permalink / raw)


The following code snippet does not compile under two compilers that
we have tried. Working with one of the vendors, we were wondering at
first whether or not it should compile as in whether the instantiation
is a freezing occurrence per 13.14:(5) and therefore the tagged
primitive operation should be illegal, per RM95 3.9.2:(13) and 13.14:
(16)

Our reasoning (with the vendor) now as to why we agree that it
shouldn't compile is based on the following. We wanted to run this by
this group for any contrarian opinions or underlying reasons why this
does not and should not compile.




From a compiler implementation perspective, the instantiation (rather
like a macro expansion) will precede the primitive operation itself,
even though the two are really conceptually coincident declarations.
Should the primitive operation be allowed, no matter what the contents
of the instantiation?

Suppose the instance elaboration happens to declare some objects, and
dispatch some primitive operations of its own type?    It would
violate the intent of the above rules.    Should this still be
allowed?     I hope not.

and also then this would NOT apply to UNTAGGED TYPES because (???)

    13.14:(16): "[The explicit declaration of a primitive subprogram
of a
    tagged type shall occur before the type is frozen (see 3.9.2).]"

    3.9.2:(13): "The explicit declaration of a primitive subprogram of
a tagged
    type shall occur before the type is frozen (see 13.14).  [For
example, new
    dispatching operations cannot be added after objects or values of
the type
    exist, nor after deriving a record extension from it, nor after a
body.]"

 Notice that Annotated Ada RM95 3.9.2:(13.c) clarifies:
   "We considered applying this rule to all derived types, for
uniformity.
    However, that would be upward incompatible, so we rejected the
idea."

That means untagged types can add more new primitive ops even after
the type is frozen.  Yes!
It seems the belief is that there's no harm in it, although  it would
be confusing (counter-intuitive)
if that primitive op was overridden because the old overridden (not
new overriding) primitive op body
would reemerge (ie, still be called), same as in Ada83.


generic
  type Object_T is private;
procedure blah ( Param : Object_T );

-------

with blah;
package oops is
  type a is tagged null record;  -- any tagged type

 -- must be a type extension to induce
failure:
  type Flight_T is new a with null record;  -- fail

  function b (Flight : in Flight_T) return String;

  procedure c is new blah
     (Object_T => Flight_T);

end;



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

* Re: tagged primitive operation and freezing
  2010-11-13  3:24 tagged primitive operation and freezing troll
@ 2010-11-13 10:24 ` Ludovic Brenta
  2010-11-15 14:23   ` troll
  0 siblings, 1 reply; 5+ messages in thread
From: Ludovic Brenta @ 2010-11-13 10:24 UTC (permalink / raw)


troll writes on comp.lang.ada:
> generic
>   type Object_T is private;
> procedure blah ( Param : Object_T );
>
> -------
>
> with blah;
> package oops is
>   type a is tagged null record;  -- any tagged type
>
>  -- must be a type extension to induce failure:
>   type Flight_T is new a with null record;  -- fail
>
>   function b (Flight : in Flight_T) return String;
>
>   procedure c is new blah (Object_T => Flight_T);
>
> end;

I think the reason why this is illegal is because c is a primitive
operation of Flight_T; at the same time, using Flight_T as an actual
generic parameter freezes Flight_T just before the declaration of this
new primitive operation.  Therefore the declaration of c is illegal.

You can work around this by wrapping Flight_T in a package:

generic
  type Object_T is private;
procedure blah ( Param : Object_T );

with blah;
package oops is
  type a is tagged null record;  -- any tagged type

  package Flight is
  -- must be a type extension to induce failure:
     type T is new a with null record;
     function b (Flight : in T) return String;
  end Flight; -- this freezes Flight_T

  procedure c is new blah (Object_T => Flight.T); -- non-primitive

end oops;

-- 
Ludovic Brenta.



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

* Re: tagged primitive operation and freezing
  2010-11-13 10:24 ` Ludovic Brenta
@ 2010-11-15 14:23   ` troll
  2010-11-15 16:30     ` Adam Beneschan
  0 siblings, 1 reply; 5+ messages in thread
From: troll @ 2010-11-15 14:23 UTC (permalink / raw)


But only if it is tagged. untagged type, even though frozen, DOES
compile.

On Nov 13, 5:24 am, Ludovic Brenta <ludo...@ludovic-brenta.org> wrote:
> troll writes on comp.lang.ada:
>
>
>
>
>
> > generic
> >   type Object_T is private;
> > procedure blah ( Param : Object_T );
>
> > -------
>
> > with blah;
> > package oops is
> >   type a is tagged null record;  -- any tagged type
>
> >  -- must be a type extension to induce failure:
> >   type Flight_T is new a with null record;  -- fail
>
> >   function b (Flight : in Flight_T) return String;
>
> >   procedure c is new blah (Object_T => Flight_T);
>
> > end;
>
> I think the reason why this is illegal is because c is a primitive
> operation of Flight_T; at the same time, using Flight_T as an actual
> generic parameter freezes Flight_T just before the declaration of this
> new primitive operation.  Therefore the declaration of c is illegal.
>
> You can work around this by wrapping Flight_T in a package:
>
> generic
>   type Object_T is private;
> procedure blah ( Param : Object_T );
>
> with blah;
> package oops is
>   type a is tagged null record;  -- any tagged type
>
>   package Flight is
>   -- must be a type extension to induce failure:
>      type T is new a with null record;
>      function b (Flight : in T) return String;
>   end Flight; -- this freezes Flight_T
>
>   procedure c is new blah (Object_T => Flight.T); -- non-primitive
>
> end oops;
>
> --
> Ludovic Brenta.- Hide quoted text -
>
> - Show quoted text -




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

* Re: tagged primitive operation and freezing
  2010-11-15 14:23   ` troll
@ 2010-11-15 16:30     ` Adam Beneschan
  2010-11-16  8:53       ` Ludovic Brenta
  0 siblings, 1 reply; 5+ messages in thread
From: Adam Beneschan @ 2010-11-15 16:30 UTC (permalink / raw)


On Nov 15, 6:23 am, troll <wisniewski...@gmail.com> wrote:
> But only if it is tagged. untagged type, even though frozen, DOES
> compile.

I think the reason for this is that when a type is frozen, a compiler
needs to be able to determine the representation of objects of the
type at that point.  For a tagged type T, the "representation" of the
object includes the tag, which is (in most or all implementations)
used to get to a table of subprogram addresses for the primitive
operations of the type.  This is needed because of dispatching; if
somewhere else in the program you call one of those operations on an
object of type T'Class, the program will need to look at the tag and
then use that to decide what subprogram to call.  This table of
subprogram addresses is considered part of the representation, and
thus the compiler needs to generate it when the type is frozen;
therefore, it's a bad thing if the compiler generates this table and
then finds out later there's a new primitive operation that didn't
make it into the table because the compiler didn't know about it.
None of this applies to untagged types, which is why the rule is
different.  Hope this helps explain things.

                              -- Adam



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

* Re: tagged primitive operation and freezing
  2010-11-15 16:30     ` Adam Beneschan
@ 2010-11-16  8:53       ` Ludovic Brenta
  0 siblings, 0 replies; 5+ messages in thread
From: Ludovic Brenta @ 2010-11-16  8:53 UTC (permalink / raw)


troll wrote on comp.lang.ada:
>> But only if it is tagged. untagged type, even though frozen, DOES
>> compile.

My initial reaction to this was: of course, because, if type A is
untagged,

type Flight_T is new A;

freezes Flight_T immediately since its representation is known,
therefore

procedure C is new Blah (Object_T => Flight_T);

is not primitive because not dynamically dispatching.

After re-reading 13.14, I see it does not discuss non-tagged types or
types derived from non-tagged types, so I'm not so sure about the
first part anymore.  And, per 3.2.3(6), C seems to be primitive after
all (primitive subprograms are not necessarily dynamically
dispatching).

While I intuitively agree with Adam's explanation, I can't find the
chapter and verse in the ARM that backs it; it seems like a gray area
to me.

--
Ludovic Brenta.



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

end of thread, other threads:[~2010-11-16  8:53 UTC | newest]

Thread overview: 5+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2010-11-13  3:24 tagged primitive operation and freezing troll
2010-11-13 10:24 ` Ludovic Brenta
2010-11-15 14:23   ` troll
2010-11-15 16:30     ` Adam Beneschan
2010-11-16  8:53       ` Ludovic Brenta

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